KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > util > jce > provider > X509CertificateObject


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.util.jce.provider;
19
20 import java.io.ByteArrayInputStream JavaDoc;
21 import java.io.ByteArrayOutputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.math.BigInteger JavaDoc;
24 import java.security.InvalidKeyException JavaDoc;
25 import java.security.NoSuchAlgorithmException JavaDoc;
26 import java.security.NoSuchProviderException JavaDoc;
27 import java.security.Principal JavaDoc;
28 import java.security.Provider JavaDoc;
29 import java.security.PublicKey JavaDoc;
30 import java.security.Security JavaDoc;
31 import java.security.Signature JavaDoc;
32 import java.security.SignatureException JavaDoc;
33 import java.security.cert.CertificateEncodingException JavaDoc;
34 import java.security.cert.CertificateException JavaDoc;
35 import java.security.cert.CertificateExpiredException JavaDoc;
36 import java.security.cert.CertificateNotYetValidException JavaDoc;
37 import java.security.cert.CertificateParsingException JavaDoc;
38 import java.security.cert.X509Certificate JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.Collections JavaDoc;
41 import java.util.Date JavaDoc;
42 import java.util.Enumeration JavaDoc;
43 import java.util.HashSet JavaDoc;
44 import java.util.Hashtable JavaDoc;
45 import java.util.List JavaDoc;
46 import java.util.Set JavaDoc;
47 import java.util.Vector JavaDoc;
48
49 import javax.security.auth.x500.X500Principal JavaDoc;
50
51 import org.apache.geronimo.util.asn1.*;
52 import org.apache.geronimo.util.asn1.misc.MiscObjectIdentifiers;
53 import org.apache.geronimo.util.asn1.misc.NetscapeCertType;
54 import org.apache.geronimo.util.asn1.misc.NetscapeRevocationURL;
55 import org.apache.geronimo.util.asn1.misc.VerisignCzagExtension;
56 import org.apache.geronimo.util.asn1.util.ASN1Dump;
57 import org.apache.geronimo.util.asn1.x509.BasicConstraints;
58 import org.apache.geronimo.util.asn1.x509.KeyUsage;
59 import org.apache.geronimo.util.asn1.x509.X509CertificateStructure;
60 import org.apache.geronimo.util.asn1.x509.X509Extension;
61 import org.apache.geronimo.util.asn1.x509.X509Extensions;
62 import org.apache.geronimo.util.jce.X509Principal;
63 import org.apache.geronimo.util.jce.interfaces.PKCS12BagAttributeCarrier;
64 import org.apache.geronimo.util.encoders.Hex;
65
66 public class X509CertificateObject
67     extends X509Certificate JavaDoc
68     implements PKCS12BagAttributeCarrier
69 {
70     private X509CertificateStructure c;
71     private Hashtable JavaDoc pkcs12Attributes = new Hashtable JavaDoc();
72     private Vector JavaDoc pkcs12Ordering = new Vector JavaDoc();
73
74     public X509CertificateObject(
75         X509CertificateStructure c)
76     {
77         this.c = c;
78     }
79
80     public void checkValidity()
81         throws CertificateExpiredException JavaDoc, CertificateNotYetValidException JavaDoc
82     {
83         this.checkValidity(new Date JavaDoc());
84     }
85
86     public void checkValidity(
87         Date JavaDoc date)
88         throws CertificateExpiredException JavaDoc, CertificateNotYetValidException JavaDoc
89     {
90         if (date.after(this.getNotAfter()))
91         {
92             throw new CertificateExpiredException JavaDoc("certificate expired on " + c.getEndDate().getTime());
93         }
94
95         if (date.before(this.getNotBefore()))
96         {
97             throw new CertificateNotYetValidException JavaDoc("certificate not valid till " + c.getStartDate().getTime());
98         }
99     }
100
101     public int getVersion()
102     {
103         return c.getVersion();
104     }
105
106     public BigInteger JavaDoc getSerialNumber()
107     {
108         return c.getSerialNumber().getValue();
109     }
110
111     public Principal JavaDoc getIssuerDN()
112     {
113         return new X509Principal(c.getIssuer());
114     }
115
116     public X500Principal JavaDoc getIssuerX500Principal()
117     {
118         try
119         {
120             ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
121             ASN1OutputStream aOut = new ASN1OutputStream(bOut);
122
123             aOut.writeObject(c.getIssuer());
124
125             return new X500Principal JavaDoc(bOut.toByteArray());
126         }
127         catch (IOException JavaDoc e)
128         {
129             throw new IllegalStateException JavaDoc("can't encode issuer DN");
130         }
131     }
132
133     public Principal JavaDoc getSubjectDN()
134     {
135         return new X509Principal(c.getSubject());
136     }
137
138     public X500Principal JavaDoc getSubjectX500Principal()
139     {
140         try
141         {
142             ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
143             ASN1OutputStream aOut = new ASN1OutputStream(bOut);
144
145             aOut.writeObject(c.getSubject());
146
147             return new X500Principal JavaDoc(bOut.toByteArray());
148         }
149         catch (IOException JavaDoc e)
150         {
151             throw new IllegalStateException JavaDoc("can't encode issuer DN");
152         }
153     }
154
155     public Date JavaDoc getNotBefore()
156     {
157         return c.getStartDate().getDate();
158     }
159
160     public Date JavaDoc getNotAfter()
161     {
162         return c.getEndDate().getDate();
163     }
164
165     public byte[] getTBSCertificate()
166         throws CertificateEncodingException JavaDoc
167     {
168         ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
169         DEROutputStream dOut = new DEROutputStream(bOut);
170
171         try
172         {
173             dOut.writeObject(c.getTBSCertificate());
174
175             return bOut.toByteArray();
176         }
177         catch (IOException JavaDoc e)
178         {
179             throw new CertificateEncodingException JavaDoc(e.toString());
180         }
181     }
182
183     public byte[] getSignature()
184     {
185         return c.getSignature().getBytes();
186     }
187
188     /**
189      * return a more "meaningful" representation for the signature algorithm used in
190      * the certficate.
191      */

192     public String JavaDoc getSigAlgName()
193     {
194         Provider JavaDoc[] provs = Security.getProviders();
195
196         //
197
// search every provider looking for a real algorithm
198
//
199
for (int i = 0; i != provs.length; i++)
200         {
201             String JavaDoc algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID());
202             if (algName != null)
203             {
204                 return algName;
205             }
206         }
207
208         return this.getSigAlgOID();
209     }
210
211     /**
212      * return the object identifier for the signature.
213      */

214     public String JavaDoc getSigAlgOID()
215     {
216         return c.getSignatureAlgorithm().getObjectId().getId();
217     }
218
219     /**
220      * return the signature parameters, or null if there aren't any.
221      */

222     public byte[] getSigAlgParams()
223     {
224         ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
225
226         if (c.getSignatureAlgorithm().getParameters() != null)
227         {
228             try
229             {
230                 DEROutputStream dOut = new DEROutputStream(bOut);
231
232                 dOut.writeObject(c.getSignatureAlgorithm().getParameters());
233             }
234             catch (Exception JavaDoc e)
235             {
236                 throw new RuntimeException JavaDoc("exception getting sig parameters " + e);
237             }
238
239             return bOut.toByteArray();
240         }
241         else
242         {
243             return null;
244         }
245     }
246
247     public boolean[] getIssuerUniqueID()
248     {
249         DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
250
251         if (id != null)
252         {
253             byte[] bytes = id.getBytes();
254             boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
255
256             for (int i = 0; i != boolId.length; i++)
257             {
258                 boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
259             }
260
261             return boolId;
262         }
263
264         return null;
265     }
266
267     public boolean[] getSubjectUniqueID()
268     {
269         DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
270
271         if (id != null)
272         {
273             byte[] bytes = id.getBytes();
274             boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
275
276             for (int i = 0; i != boolId.length; i++)
277             {
278                 boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
279             }
280
281             return boolId;
282         }
283
284         return null;
285     }
286
287     public boolean[] getKeyUsage()
288     {
289         byte[] bytes = this.getExtensionBytes("2.5.29.15");
290         int length = 0;
291
292         if (bytes != null)
293         {
294             try
295             {
296                 ASN1InputStream dIn = new ASN1InputStream(new ByteArrayInputStream JavaDoc(bytes));
297                 DERBitString bits = (DERBitString)dIn.readObject();
298
299                 bytes = bits.getBytes();
300                 length = (bytes.length * 8) - bits.getPadBits();
301             }
302             catch (Exception JavaDoc e)
303             {
304                 throw new RuntimeException JavaDoc("error processing key usage extension");
305             }
306
307             boolean[] keyUsage = new boolean[(length < 9) ? 9 : length];
308
309             for (int i = 0; i != length; i++)
310             {
311                 keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
312             }
313
314             return keyUsage;
315         }
316
317         return null;
318     }
319
320     public List JavaDoc getExtendedKeyUsage()
321         throws CertificateParsingException JavaDoc
322     {
323         byte[] bytes = this.getExtensionBytes("2.5.29.37");
324         int length = 0;
325
326         if (bytes != null)
327         {
328             try
329             {
330                 ASN1InputStream dIn = new ASN1InputStream(new ByteArrayInputStream JavaDoc(bytes));
331                 ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
332                 ArrayList JavaDoc list = new ArrayList JavaDoc();
333
334                 for (int i = 0; i != seq.size(); i++)
335                 {
336                     list.add(((DERObjectIdentifier)seq.getObjectAt(i)).getId());
337                 }
338
339                 return Collections.unmodifiableList(list);
340             }
341             catch (Exception JavaDoc e)
342             {
343                 throw new CertificateParsingException JavaDoc("error processing extended key usage extension");
344             }
345         }
346
347         return null;
348     }
349
350     public int getBasicConstraints()
351     {
352         byte[] bytes = this.getExtensionBytes("2.5.29.19");
353
354         if (bytes != null)
355         {
356             try
357             {
358                 ASN1InputStream dIn = new ASN1InputStream(new ByteArrayInputStream JavaDoc(bytes));
359                 ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
360
361                 if (seq.size() == 2)
362                 {
363                     if (((DERBoolean)seq.getObjectAt(0)).isTrue())
364                     {
365                         return ((DERInteger)seq.getObjectAt(1)).getValue().intValue();
366                     }
367                     else
368                     {
369                         return -1;
370                     }
371                 }
372                 else if (seq.size() == 1)
373                 {
374                     if (seq.getObjectAt(0) instanceof DERBoolean)
375                     {
376                         if (((DERBoolean)seq.getObjectAt(0)).isTrue())
377                         {
378                             return Integer.MAX_VALUE;
379                         }
380                         else
381                         {
382                             return -1;
383                         }
384                     }
385                     else
386                     {
387                         return -1;
388                     }
389                 }
390             }
391             catch (Exception JavaDoc e)
392             {
393                 throw new RuntimeException JavaDoc("error processing key usage extension");
394             }
395         }
396
397         return -1;
398     }
399
400     public Set JavaDoc getCriticalExtensionOIDs()
401     {
402         if (this.getVersion() == 3)
403         {
404             HashSet JavaDoc set = new HashSet JavaDoc();
405             X509Extensions extensions = c.getTBSCertificate().getExtensions();
406
407             if (extensions != null)
408             {
409                 Enumeration JavaDoc e = extensions.oids();
410
411                 while (e.hasMoreElements())
412                 {
413                     DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
414                     X509Extension ext = extensions.getExtension(oid);
415
416                     if (ext.isCritical())
417                     {
418                         set.add(oid.getId());
419                     }
420                 }
421
422                 return set;
423             }
424         }
425
426         return null;
427     }
428
429     private byte[] getExtensionBytes(String JavaDoc oid)
430     {
431         X509Extensions exts = c.getTBSCertificate().getExtensions();
432
433         if (exts != null)
434         {
435             X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid));
436             if (ext != null)
437             {
438                 return ext.getValue().getOctets();
439             }
440         }
441
442         return null;
443     }
444
445     public byte[] getExtensionValue(String JavaDoc oid)
446     {
447         X509Extensions exts = c.getTBSCertificate().getExtensions();
448
449         if (exts != null)
450         {
451             X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid));
452
453             if (ext != null)
454             {
455                 ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
456                 DEROutputStream dOut = new DEROutputStream(bOut);
457
458                 try
459                 {
460                     dOut.writeObject(ext.getValue());
461
462                     return bOut.toByteArray();
463                 }
464                 catch (Exception JavaDoc e)
465                 {
466                     throw new RuntimeException JavaDoc("error encoding " + e.toString());
467                 }
468             }
469         }
470
471         return null;
472     }
473
474     public Set JavaDoc getNonCriticalExtensionOIDs()
475     {
476         if (this.getVersion() == 3)
477         {
478             HashSet JavaDoc set = new HashSet JavaDoc();
479             X509Extensions extensions = c.getTBSCertificate().getExtensions();
480
481             if (extensions != null)
482             {
483                 Enumeration JavaDoc e = extensions.oids();
484
485                 while (e.hasMoreElements())
486                 {
487                     DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
488                     X509Extension ext = extensions.getExtension(oid);
489
490                     if (!ext.isCritical())
491                     {
492                         set.add(oid.getId());
493                     }
494                 }
495
496                 return set;
497             }
498         }
499
500         return null;
501     }
502
503     public boolean hasUnsupportedCriticalExtension()
504     {
505         if (this.getVersion() == 3)
506         {
507             X509Extensions extensions = c.getTBSCertificate().getExtensions();
508
509             if (extensions != null)
510             {
511                 Enumeration JavaDoc e = extensions.oids();
512
513                 while (e.hasMoreElements())
514                 {
515                     DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
516                     if (oid.getId().equals("2.5.29.15")
517                        || oid.getId().equals("2.5.29.19"))
518                     {
519                         continue;
520                     }
521
522                     X509Extension ext = extensions.getExtension(oid);
523
524                     if (ext.isCritical())
525                     {
526                         return true;
527                     }
528                 }
529             }
530         }
531
532         return false;
533     }
534
535     public PublicKey JavaDoc getPublicKey()
536     {
537         return JDKKeyFactory.createPublicKeyFromPublicKeyInfo(c.getSubjectPublicKeyInfo());
538     }
539
540     public byte[] getEncoded()
541         throws CertificateEncodingException JavaDoc
542     {
543         ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
544         DEROutputStream dOut = new DEROutputStream(bOut);
545
546         try
547         {
548             dOut.writeObject(c);
549
550             return bOut.toByteArray();
551         }
552         catch (IOException JavaDoc e)
553         {
554             throw new CertificateEncodingException JavaDoc(e.toString());
555         }
556     }
557
558     public void setBagAttribute(
559         DERObjectIdentifier oid,
560         DEREncodable attribute)
561     {
562         pkcs12Attributes.put(oid, attribute);
563         pkcs12Ordering.addElement(oid);
564     }
565
566     public DEREncodable getBagAttribute(
567         DERObjectIdentifier oid)
568     {
569         return (DEREncodable)pkcs12Attributes.get(oid);
570     }
571
572     public Enumeration JavaDoc getBagAttributeKeys()
573     {
574         return pkcs12Ordering.elements();
575     }
576
577     public String JavaDoc toString()
578     {
579         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
580         String JavaDoc nl = System.getProperty("line.separator");
581
582         buf.append(" [0] Version: " + this.getVersion() + nl);
583         buf.append(" SerialNumber: " + this.getSerialNumber() + nl);
584         buf.append(" IssuerDN: " + this.getIssuerDN() + nl);
585         buf.append(" Start Date: " + this.getNotBefore() + nl);
586         buf.append(" Final Date: " + this.getNotAfter() + nl);
587         buf.append(" SubjectDN: " + this.getSubjectDN() + nl);
588         buf.append(" Public Key: " + this.getPublicKey() + nl);
589         buf.append(" Signature Algorithm: " + this.getSigAlgName() + nl);
590
591         byte[] sig = this.getSignature();
592
593         buf.append(" Signature: " + new String JavaDoc(Hex.encode(sig, 0, 20)) + nl);
594         for (int i = 20; i < sig.length; i += 20)
595         {
596             if (i < sig.length - 20)
597             {
598                 buf.append(" " + new String JavaDoc(Hex.encode(sig, i, 20)) + nl);
599             }
600             else
601             {
602                 buf.append(" " + new String JavaDoc(Hex.encode(sig, i, sig.length - i)) + nl);
603             }
604         }
605
606         X509Extensions extensions = c.getTBSCertificate().getExtensions();
607
608         if (extensions != null)
609         {
610             Enumeration JavaDoc e = extensions.oids();
611
612             if (e.hasMoreElements())
613             {
614                 buf.append(" Extensions: \n");
615             }
616
617             while (e.hasMoreElements())
618             {
619                 DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
620                 X509Extension ext = extensions.getExtension(oid);
621
622                 if (ext.getValue() != null)
623                 {
624                     byte[] octs = ext.getValue().getOctets();
625                     ByteArrayInputStream JavaDoc bIn = new ByteArrayInputStream JavaDoc(octs);
626                     ASN1InputStream dIn = new ASN1InputStream(bIn);
627                     buf.append(" critical(" + ext.isCritical() + ") ");
628                     try
629                     {
630                         if (oid.equals(X509Extensions.BasicConstraints))
631                         {
632                             buf.append(new BasicConstraints((ASN1Sequence)dIn.readObject()) + nl);
633                         }
634                         else if (oid.equals(X509Extensions.KeyUsage))
635                         {
636                             buf.append(new KeyUsage((DERBitString)dIn.readObject()) + nl);
637                         }
638                         else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
639                         {
640                             buf.append(new NetscapeCertType((DERBitString)dIn.readObject()) + nl);
641                         }
642                         else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
643                         {
644                             buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject()) + nl);
645                         }
646                         else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
647                         {
648                             buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject()) + nl);
649                         }
650                         else
651                         {
652                             buf.append(oid.getId());
653                             buf.append(" value = " + ASN1Dump.dumpAsString(dIn.readObject()) + nl);
654                             //buf.append(" value = " + "*****" + nl);
655
}
656                     }
657                     catch (Exception JavaDoc ex)
658                     {
659                         buf.append(oid.getId());
660                    // buf.append(" value = " + new String(Hex.encode(ext.getValue().getOctets())) + nl);
661
buf.append(" value = " + "*****" + nl);
662                     }
663                 }
664                 else
665                 {
666                     buf.append(nl);
667                 }
668             }
669         }
670
671         return buf.toString();
672     }
673
674     public final void verify(
675         PublicKey JavaDoc key)
676         throws CertificateException JavaDoc, NoSuchAlgorithmException JavaDoc,
677         InvalidKeyException JavaDoc, NoSuchProviderException JavaDoc, SignatureException JavaDoc
678     {
679         Signature JavaDoc signature = null;
680
681         if (!c.getSignatureAlgorithm().equals(c.getTBSCertificate().getSignature()))
682         {
683             throw new CertificateException JavaDoc("signature algorithm in TBS cert not same as outer cert");
684         }
685
686         try
687         {
688             signature = Signature.getInstance(c.getSignatureAlgorithm().getObjectId().getId(), "BC");
689         }
690         catch (Exception JavaDoc e)
691         {
692             signature = Signature.getInstance(c.getSignatureAlgorithm().getObjectId().getId());
693         }
694
695         signature.initVerify(key);
696
697         signature.update(this.getTBSCertificate());
698
699         if (!signature.verify(this.getSignature()))
700         {
701             throw new InvalidKeyException JavaDoc("Public key presented not for certificate signature");
702         }
703     }
704
705     public final void verify(
706         PublicKey JavaDoc key,
707         String JavaDoc sigProvider)
708         throws CertificateException JavaDoc, NoSuchAlgorithmException JavaDoc,
709         InvalidKeyException JavaDoc, NoSuchProviderException JavaDoc, SignatureException JavaDoc
710     {
711         Signature JavaDoc signature = Signature.getInstance(c.getSignatureAlgorithm().getObjectId().getId(), sigProvider);
712
713         if (!c.getSignatureAlgorithm().equals(c.getTBSCertificate().getSignature()))
714         {
715             throw new CertificateException JavaDoc("signature algorithm in TBS cert not same as outer cert");
716         }
717
718         signature.initVerify(key);
719
720         signature.update(this.getTBSCertificate());
721
722         if (!signature.verify(this.getSignature()))
723         {
724             throw new InvalidKeyException JavaDoc("Public key presented not for certificate signature");
725         }
726     }
727 }
728
Popular Tags