/[classpath]/classpath/gnu/java/security/x509/X509Certificate.java
ViewVC logotype

Diff of /classpath/gnu/java/security/x509/X509Certificate.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by mkoch, Wed Jun 18 10:01:34 2003 UTC revision 1.3.2.1 by gnu_andrew, Sun Jan 16 02:14:46 2005 UTC
# Line 1  Line 1 
1  /* X509Certificate.java -- X.509 certificate.  /* X509Certificate.java -- X.509 certificate.
2     Copyright (C) 2003 Free Software Foundation, Inc.     Copyright (C) 2003, 2004  Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 7  GNU Classpath is free software; you can Line 7  GNU Classpath is free software; you can
7  it under the terms of the GNU General Public License as published by  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)  the Free Software Foundation; either version 2, or (at your option)
9  any later version.  any later version.
10    
11  GNU Classpath is distributed in the hope that it will be useful, but  GNU Classpath is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Line 42  import java.io.ByteArrayInputStream; Line 42  import java.io.ByteArrayInputStream;
42  import java.io.InputStream;  import java.io.InputStream;
43  import java.io.IOException;  import java.io.IOException;
44  import java.io.ObjectStreamException;  import java.io.ObjectStreamException;
45    import java.io.PrintWriter;
46  import java.io.Serializable;  import java.io.Serializable;
47    import java.io.StringWriter;
48    
49  import java.math.BigInteger;  import java.math.BigInteger;
50    
# Line 64  import java.security.cert.CertificateExp Line 66  import java.security.cert.CertificateExp
66  import java.security.cert.CertificateNotYetValidException;  import java.security.cert.CertificateNotYetValidException;
67  import java.security.cert.CertificateParsingException;  import java.security.cert.CertificateParsingException;
68    
69    import java.security.interfaces.DSAParams;
70    import java.security.interfaces.DSAPublicKey;
71  import java.security.spec.DSAParameterSpec;  import java.security.spec.DSAParameterSpec;
72  import java.security.spec.DSAPublicKeySpec;  import java.security.spec.X509EncodedKeySpec;
 import java.security.spec.RSAPublicKeySpec;  
73    
74    import java.util.Arrays;
75  import java.util.ArrayList;  import java.util.ArrayList;
76  import java.util.Collection;  import java.util.Collection;
77  import java.util.Collections;  import java.util.Collections;
# Line 77  import java.util.HashSet; Line 81  import java.util.HashSet;
81  import java.util.Iterator;  import java.util.Iterator;
82  import java.util.LinkedList;  import java.util.LinkedList;
83  import java.util.List;  import java.util.List;
84    import java.util.Map;
85  import java.util.Set;  import java.util.Set;
86    
87  import javax.security.auth.x500.X500Principal;  import javax.security.auth.x500.X500Principal;
88    
 import gnu.java.io.ASN1ParsingException;  
89  import gnu.java.security.OID;  import gnu.java.security.OID;
90  import gnu.java.security.der.BitString;  import gnu.java.security.der.*;
91  import gnu.java.security.der.DER;  import gnu.java.security.x509.ext.*;
 import gnu.java.security.der.DERReader;  
 import gnu.java.security.der.DERValue;  
 import gnu.java.security.der.DERWriter;  
92    
93  /**  /**
94   * An implementation of X.509 certificates.   * An implementation of X.509 certificates.
# Line 95  import gnu.java.security.der.DERWriter; Line 96  import gnu.java.security.der.DERWriter;
96   * @author Casey Marshall (rsdio@metastatic.org)   * @author Casey Marshall (rsdio@metastatic.org)
97   */   */
98  public class X509Certificate extends java.security.cert.X509Certificate  public class X509Certificate extends java.security.cert.X509Certificate
99    implements Serializable    implements Serializable, GnuPKIExtension
100  {  {
101    
102    // Constants and fields.    // Constants and fields.
103    // ------------------------------------------------------------------------    // ------------------------------------------------------------------------
104    
105    private static final OID ID_DSA = new OID("1.2.840.10040.4.1");    private static final boolean DEBUG = false;
106    private static final OID ID_DSA_WITH_SHA1 = new OID("1.2.840.10040.4.3");    private static void debug(String msg)
107    private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");    {
108    private static final OID ID_RSA_WITH_MD2 = new OID("1.2.840.113549.1.1.2");      if (DEBUG)
109    private static final OID ID_RSA_WITH_MD5 = new OID("1.2.840.113549.1.1.4");        {
110    private static final OID ID_RSA_WITH_SHA1 = new OID("1.2.840.113549.1.1.5");          System.err.print(">> X509Certificate: ");
111            System.err.println(msg);
112    private static final OID ID_EXTENSION = new OID("2.5.29");        }
113    private static final OID ID_KEY_USAGE = ID_EXTENSION.getChild(15);    }
114    private static final OID ID_BASIC_CONSTRAINTS = ID_EXTENSION.getChild(19);    private static void debug(Throwable t)
115    private static final OID ID_EXT_KEY_USAGE = ID_EXTENSION.getChild(37);    {
116        if (DEBUG)
117    private static final int OTHER_NAME     = 0;        {
118    private static final int RFC882_NAME    = 1;          System.err.print(">> X509Certificate: ");
119    private static final int DNS_NAME       = 2;          t.printStackTrace();
120    private static final int X400_ADDRESS   = 3;        }
121    private static final int DIRECTORY_NAME = 4;    }
122    private static final int EDI_PARTY_NAME = 5;  
123    private static final int URI            = 6;    protected static final OID ID_DSA = new OID ("1.2.840.10040.4.1");
124    private static final int IP_ADDRESS     = 7;    protected static final OID ID_DSA_WITH_SHA1 = new OID ("1.2.840.10040.4.3");
125    private static final int REGISTERED_ID  = 8;    protected static final OID ID_RSA = new OID ("1.2.840.113549.1.1.1");
126      protected static final OID ID_RSA_WITH_MD2 = new OID ("1.2.840.113549.1.1.2");
127      protected static final OID ID_RSA_WITH_MD5 = new OID ("1.2.840.113549.1.1.4");
128      protected static final OID ID_RSA_WITH_SHA1 = new OID ("1.2.840.113549.1.1.5");
129      protected static final OID ID_ECDSA_WITH_SHA1 = new OID ("1.2.840.10045.4.1");
130    
131    // This object SHOULD be serialized with an instance of    // This object SHOULD be serialized with an instance of
132    // java.security.cert.Certificate.CertificateRep, thus all fields are    // java.security.cert.Certificate.CertificateRep, thus all fields are
133    // transient.    // transient.
134    
135    // The encoded certificate.    // The encoded certificate.
136    private transient byte[] encoded;    protected transient byte[] encoded;
137    
138    // TBSCertificate part.    // TBSCertificate part.
139    private transient byte[] tbsCertBytes;    protected transient byte[] tbsCertBytes;
140    private transient int version;    protected transient int version;
141    private transient BigInteger serialNo;    protected transient BigInteger serialNo;
142    private transient OID algId;    protected transient OID algId;
143    private transient byte[] algVal;    protected transient byte[] algVal;
144    private transient X500Principal issuer;    protected transient X500DistinguishedName issuer;
145    private transient Date notBefore;    protected transient Date notBefore;
146    private transient Date notAfter;    protected transient Date notAfter;
147    private transient X500Principal subject;    protected transient X500DistinguishedName subject;
148    private transient PublicKey subjectKey;    protected transient PublicKey subjectKey;
149    private transient BitString issuerUniqueId;    protected transient BitString issuerUniqueId;
150    private transient BitString subjectUniqueId;    protected transient BitString subjectUniqueId;
151    private transient HashMap extensions;    protected transient Map extensions;
   private transient HashSet critOids;  
   private transient HashSet nonCritOids;  
     
   private transient BitString keyUsage;  
   private transient int basicConstraints = -1;  
152    
153    // Signature.    // Signature.
154    private transient OID sigAlgId;    protected transient OID sigAlgId;
155    private transient byte[] sigAlgVal;    protected transient byte[] sigAlgVal;
156    private transient byte[] signature;    protected transient byte[] signature;
157    
158    // Constructors.    // Constructors.
159    // ------------------------------------------------------------------------    // ------------------------------------------------------------------------
# Line 173  public class X509Certificate extends jav Line 173  public class X509Certificate extends jav
173    {    {
174      super();      super();
175      extensions = new HashMap();      extensions = new HashMap();
     critOids = new HashSet();  
     nonCritOids = new HashSet();  
176      try      try
177        {        {
178          parse(encoded);          parse(encoded);
179        }        }
180      catch (IOException ioe)      catch (IOException ioe)
181        {        {
182            debug(ioe);
183          throw ioe;          throw ioe;
184        }        }
185      catch (Exception e)      catch (Exception e)
186        {        {
187          throw new CertificateException(e.toString());          debug(e);
188            CertificateException ce = new CertificateException(e.getMessage());
189            ce.initCause (e);
190            throw ce;
191        }        }
192    }    }
193    
194      protected X509Certificate()
195      {
196        extensions = new HashMap();
197      }
198    
199    // X509Certificate methods.    // X509Certificate methods.
200    // ------------------------------------------------------------------------    // ------------------------------------------------------------------------
201    
# Line 202  public class X509Certificate extends jav Line 209  public class X509Certificate extends jav
209      throws CertificateExpiredException, CertificateNotYetValidException      throws CertificateExpiredException, CertificateNotYetValidException
210    {    {
211      if (date.compareTo(notBefore) < 0)      if (date.compareTo(notBefore) < 0)
212        throw new CertificateNotYetValidException();        {
213            throw new CertificateNotYetValidException();
214          }
215      if (date.compareTo(notAfter) > 0)      if (date.compareTo(notAfter) > 0)
216        throw new CertificateExpiredException();        {
217            throw new CertificateExpiredException();
218          }
219    }    }
220    
221    public int getVersion()    public int getVersion()
# Line 219  public class X509Certificate extends jav Line 230  public class X509Certificate extends jav
230    
231    public Principal getIssuerDN()    public Principal getIssuerDN()
232    {    {
233      return getIssuerX500Principal();      return issuer;
234    }    }
235    
236    public X500Principal getIssuerX500Principal()    public X500Principal getIssuerX500Principal()
237    {    {
238      return issuer;      return new X500Principal(issuer.getDer());
239    }    }
240    
241    public Principal getSubjectDN()    public Principal getSubjectDN()
242    {    {
243      return getSubjectX500Principal();      return subject;
244    }    }
245    
246    public X500Principal getSubjectX500Principal()    public X500Principal getSubjectX500Principal()
247    {    {
248      return subject;      return new X500Principal(subject.getDer());
249    }    }
250    
251    public Date getNotBefore()    public Date getNotBefore()
# Line 260  public class X509Certificate extends jav Line 271  public class X509Certificate extends jav
271    public String getSigAlgName()    public String getSigAlgName()
272    {    {
273      if (sigAlgId.equals(ID_DSA_WITH_SHA1))      if (sigAlgId.equals(ID_DSA_WITH_SHA1))
274        return "SHA1withDSA";        {
275      if (sigAlgId.equals(ID_RSA_WITH_MD2 ))          return "SHA1withDSA";
276        return "MD2withRSA";        }
277      if (sigAlgId.equals(ID_RSA_WITH_MD5 ))      if (sigAlgId.equals(ID_RSA_WITH_MD2))
278        return "MD5withRSA";        {
279      if (sigAlgId.equals(ID_RSA_WITH_SHA1 ))          return "MD2withRSA";
280        return "SHA1withRSA";        }
281        if (sigAlgId.equals(ID_RSA_WITH_MD5))
282          {
283            return "MD5withRSA";
284          }
285        if (sigAlgId.equals(ID_RSA_WITH_SHA1))
286          {
287            return "SHA1withRSA";
288          }
289      return "unknown";      return "unknown";
     // return sigAlgId.getShortName();  
290    }    }
291    
292    public String getSigAlgOID()    public String getSigAlgOID()
# Line 284  public class X509Certificate extends jav Line 302  public class X509Certificate extends jav
302    public boolean[] getIssuerUniqueID()    public boolean[] getIssuerUniqueID()
303    {    {
304      if (issuerUniqueId != null)      if (issuerUniqueId != null)
305        return issuerUniqueId.toBooleanArray();        {
306            return issuerUniqueId.toBooleanArray();
307          }
308      return null;      return null;
309    }    }
310    
311    public boolean[] getSubjectUniqueID()    public boolean[] getSubjectUniqueID()
312    {    {
313      if (subjectUniqueId != null)      if (subjectUniqueId != null)
314        return subjectUniqueId.toBooleanArray();        {
315            return subjectUniqueId.toBooleanArray();
316          }
317      return null;      return null;
318    }    }
319    
320    public boolean[] getKeyUsage()    public boolean[] getKeyUsage()
321    {    {
322      if (keyUsage != null)      Extension e = getExtension(KeyUsage.ID);
323        return keyUsage.toBooleanArray();      if (e != null)
324          {
325            KeyUsage ku = (KeyUsage) e.getValue();
326            boolean[] result = new boolean[9];
327            boolean[] b = ku.getKeyUsage().toBooleanArray();
328            System.arraycopy(b, 0, result, 0, b.length);
329            return result;
330          }
331      return null;      return null;
332    }    }
333    
334    public List getExtendedKeyUsage() throws CertificateParsingException    public List getExtendedKeyUsage() throws CertificateParsingException
335    {    {
336      byte[] ext = (byte[]) extensions.get("2.5.29.37");      Extension e = getExtension(ExtendedKeyUsage.ID);
337      if (ext == null)      if (e != null)
       return null;  
     LinkedList usages = new LinkedList();  
     try  
338        {        {
339          DERReader der = new DERReader(new ByteArrayInputStream(ext));          List a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds();
340          DERValue seq = der.read();          List b = new ArrayList(a.size());
341          if (!seq.isConstructed())          for (Iterator it = a.iterator(); it.hasNext(); )
           throw new CertificateParsingException();  
         int len = 0;  
         while (len < seq.getLength())  
342            {            {
343              DERValue oid = der.read();              b.add(it.next().toString());
             if (!(oid.getValue() instanceof OID))  
               throw new CertificateParsingException();  
             usages.add(oid.getValue().toString());  
             len += DERWriter.definiteEncodingSize(oid.getLength())  
                  + oid.getLength() + 1;  
344            }            }
345            return Collections.unmodifiableList(b);
346        }        }
347      catch (IOException ioe)      return null;
       {  
         throw new CertificateParsingException();  
       }  
     return usages;  
348    }    }
349    
350    public int getBasicConstraints()    public int getBasicConstraints()
351    {    {
352      return basicConstraints;      Extension e = getExtension(BasicConstraints.ID);
353        if (e != null)
354          {
355            return ((BasicConstraints) e.getValue()).getPathLengthConstraint();
356          }
357        return -1;
358    }    }
359    
360    public Collection getSubjectAlternativeNames()    public Collection getSubjectAlternativeNames()
361      throws CertificateParsingException      throws CertificateParsingException
362    {    {
363      byte[] ext = getExtensionValue("2.5.29.17");      Extension e = getExtension(SubjectAlternativeNames.ID);
364      if (ext == null)      if (e != null)
365        return null;        {
366      return getAltNames(ext);          return ((SubjectAlternativeNames) e.getValue()).getNames();
367          }
368        return null;
369    }    }
370    
371    public Collection getIssuerAlternativeNames()    public Collection getIssuerAlternativeNames()
372      throws CertificateParsingException      throws CertificateParsingException
373    {    {
374      byte[] ext = getExtensionValue("2.5.29.18");      Extension e = getExtension(IssuerAlternativeNames.ID);
375      if (ext == null)      if (e != null)
376        return null;        {
377      return getAltNames(ext);          return ((IssuerAlternativeNames) e.getValue()).getNames();
378          }
379        return null;
380    }    }
381    
382   // X509Extension methods.   // X509Extension methods.
# Line 360  public class X509Certificate extends jav Line 384  public class X509Certificate extends jav
384    
385    public boolean hasUnsupportedCriticalExtension()    public boolean hasUnsupportedCriticalExtension()
386    {    {
387      for (Iterator it = critOids.iterator(); it.hasNext(); )      for (Iterator it = extensions.values().iterator(); it.hasNext(); )
388        {        {
389          String oid = (String) it.next();          Extension e = (Extension) it.next();
390          if (!oid.equals("2.5.29.15") && !oid.equals("2.5.29.17") &&          if (e.isCritical() && !e.isSupported())
             !oid.equals("2.5.29.18") && !oid.equals("2.5.29.19") &&  
             !oid.equals("2.5.29.37"))  
391            return true;            return true;
392        }        }
393      return false;      return false;
# Line 373  public class X509Certificate extends jav Line 395  public class X509Certificate extends jav
395    
396    public Set getCriticalExtensionOIDs()    public Set getCriticalExtensionOIDs()
397    {    {
398      return Collections.unmodifiableSet(critOids);      HashSet s = new HashSet();
399        for (Iterator it = extensions.values().iterator(); it.hasNext(); )
400          {
401            Extension e = (Extension) it.next();
402            if (e.isCritical())
403              s.add(e.getOid().toString());
404          }
405        return Collections.unmodifiableSet(s);
406    }    }
407    
408    public Set getNonCriticalExtensionOIDs()    public Set getNonCriticalExtensionOIDs()
409    {    {
410      return Collections.unmodifiableSet(nonCritOids);      HashSet s = new HashSet();
411        for (Iterator it = extensions.values().iterator(); it.hasNext(); )
412          {
413            Extension e = (Extension) it.next();
414            if (!e.isCritical())
415              s.add(e.getOid().toString());
416          }
417        return Collections.unmodifiableSet(s);
418    }    }
419    
420    public byte[] getExtensionValue(String oid)    public byte[] getExtensionValue(String oid)
421    {    {
422      byte[] ext = (byte[]) extensions.get(oid);      Extension e = getExtension(new OID(oid));
423      if (ext != null)      if (e != null)
424        return (byte[]) ext.clone();        {
425            return e.getValue().getEncoded();
426          }
427      return null;      return null;
428    }    }
429    
430      // GnuPKIExtension method.
431      // -------------------------------------------------------------------------
432    
433      public Extension getExtension(OID oid)
434      {
435        return (Extension) extensions.get(oid);
436      }
437    
438      public Collection getExtensions()
439      {
440        return extensions.values();
441      }
442    
443    // Certificate methods.    // Certificate methods.
444    // ------------------------------------------------------------------------    // -------------------------------------------------------------------------
445    
446    public byte[] getEncoded() throws CertificateEncodingException    public byte[] getEncoded() throws CertificateEncodingException
447    {    {
# Line 398  public class X509Certificate extends jav Line 449  public class X509Certificate extends jav
449    }    }
450    
451    public void verify(PublicKey key)    public void verify(PublicKey key)
452      throws CertificateException, NoSuchAlgorithmException,      throws CertificateException, NoSuchAlgorithmException,
453             InvalidKeyException, NoSuchProviderException, SignatureException             InvalidKeyException, NoSuchProviderException, SignatureException
454    {    {
455      Signature sig = Signature.getInstance(sigAlgId.toString());      Signature sig = Signature.getInstance(sigAlgId.toString());
# Line 415  public class X509Certificate extends jav Line 466  public class X509Certificate extends jav
466    
467    public String toString()    public String toString()
468    {    {
469      // XXX say more than this.      StringWriter str = new StringWriter();
470      return gnu.java.security.x509.X509Certificate.class.getName();      PrintWriter out = new PrintWriter(str);
471        out.println(X509Certificate.class.getName() + " {");
472        out.println("  TBSCertificate {");
473        out.println("    version = " + version + ";");
474        out.println("    serialNo = " + serialNo + ";");
475        out.println("    signature = {");
476        out.println("      algorithm = " + getSigAlgName() + ";");
477        out.print("      parameters =");
478        if (sigAlgVal != null)
479          {
480            out.println();
481            out.print(Util.hexDump(sigAlgVal, "        "));
482          }
483        else
484          {
485            out.println(" null;");
486          }
487        out.println("    }");
488        out.println("    issuer = " + issuer.getName() + ";");
489        out.println("    validity = {");
490        out.println("      notBefore = " + notBefore + ";");
491        out.println("      notAfter  = " + notAfter + ";");
492        out.println("    }");
493        out.println("    subject = " + subject.getName() + ";");
494        out.println("    subjectPublicKeyInfo = {");
495        out.println("      algorithm = " + subjectKey.getAlgorithm());
496        out.println("      key =");
497        out.print(Util.hexDump(subjectKey.getEncoded(), "        "));
498        out.println("    };");
499        out.println("    issuerUniqueId  = " + issuerUniqueId + ";");
500        out.println("    subjectUniqueId = " + subjectUniqueId + ";");
501        out.println("    extensions = {");
502        for (Iterator it = extensions.values().iterator(); it.hasNext(); )
503          {
504            out.println("      " + it.next());
505          }
506        out.println("    }");
507        out.println("  }");
508        out.println("  signatureAlgorithm = " + getSigAlgName() + ";");
509        out.println("  signatureValue =");
510        out.print(Util.hexDump(signature, "    "));
511        out.println("}");
512        return str.toString();
513    }    }
514    
515    public PublicKey getPublicKey()    public PublicKey getPublicKey()
# Line 424  public class X509Certificate extends jav Line 517  public class X509Certificate extends jav
517      return subjectKey;      return subjectKey;
518    }    }
519    
520    protected Object writeReplace() throws ObjectStreamException    public boolean equals(Object other)
521    {    {
522      return super.writeReplace();      if (!(other instanceof X509Certificate))
523          return false;
524        try
525          {
526            if (other instanceof X509Certificate)
527              return Arrays.equals(encoded, ((X509Certificate) other).encoded);
528            byte[] enc = ((X509Certificate) other).getEncoded();
529            if (enc == null)
530              return false;
531            return Arrays.equals(encoded, enc);
532          }
533        catch (CertificateEncodingException cee)
534          {
535            return false;
536          }
537    }    }
538      
539    // Own methods.    // Own methods.
540    // ------------------------------------------------------------------------    // ------------------------------------------------------------------------
541    
# Line 438  public class X509Certificate extends jav Line 545  public class X509Certificate extends jav
545    private void doVerify(Signature sig, PublicKey key)    private void doVerify(Signature sig, PublicKey key)
546      throws CertificateException, InvalidKeyException, SignatureException      throws CertificateException, InvalidKeyException, SignatureException
547    {    {
548        debug("verifying sig=" + sig + " key=" + key);
549      sig.initVerify(key);      sig.initVerify(key);
550      sig.update(tbsCertBytes);      sig.update(tbsCertBytes);
551      if (!sig.verify(signature))      if (!sig.verify(signature))
       throw new CertificateException("signature not validated");  
   }  
   
   /**  
    * Read a GeneralNames structure.  
    */  
   private List getAltNames(byte[] encoded)  
     throws CertificateParsingException  
   {  
     LinkedList names = new LinkedList();  
     try  
552        {        {
553          ByteArrayInputStream in = new ByteArrayInputStream(encoded);          throw new CertificateException("signature not validated");
         DERReader der = new DERReader(in);  
         DERValue seq = der.read();  
         if (!seq.isConstructed())  
           throw new CertificateParsingException();  
         int len = 0;  
         while (len < seq.getLength())  
           {  
             DERValue name = der.read();  
             ArrayList pair = new ArrayList(2);  
             Object nameVal = null;  
             switch (name.getTag())  
               {  
                 case RFC882_NAME:  
                 case DNS_NAME:  
                 case URI:  
                   nameVal = new String((byte[]) name.getValue());  
                   break;  
                 case IP_ADDRESS:  
                   nameVal = InetAddress.getByAddress(  
                     (byte[]) name.getValue()).getHostAddress();  
                   break;  
                 case REGISTERED_ID:  
                   nameVal = new OID((byte[]) name.getValue());  
                   break;  
                 case OTHER_NAME:  
                 case X400_ADDRESS:  
                 case DIRECTORY_NAME:  
                 case EDI_PARTY_NAME:  
                   nameVal = name.getEncoded();  
                   break;  
                 default:  
                   throw new CertificateParsingException();  
               }  
             pair.add(new Integer(name.getTag()));  
             pair.add(nameVal);  
             names.add(pair);  
             if (name.isConstructed())  
               in.skip(name.getLength());  
             len += name.getEncodedLength();  
           }  
554        }        }
     catch (IOException ioe)  
       {  
         throw new CertificateParsingException(ioe.toString());  
       }  
     return Collections.unmodifiableList(names);  
555    }    }
556    
557    /**    /**
# Line 513  public class X509Certificate extends jav Line 565  public class X509Certificate extends jav
565    
566      // Certificate ::= SEQUENCE {      // Certificate ::= SEQUENCE {
567      DERValue cert = der.read();      DERValue cert = der.read();
568        debug("start Certificate  len == " + cert.getLength());
569    
570      this.encoded = cert.getEncoded();      this.encoded = cert.getEncoded();
571      if (!cert.isConstructed())      if (!cert.isConstructed())
572        throw new ASN1ParsingException("malformed Certificate");        {
573            throw new IOException("malformed Certificate");
574          }
575    
576      // TBSCertificate ::= SEQUENCE {      // TBSCertificate ::= SEQUENCE {
577      DERValue tbsCert = der.read();      DERValue tbsCert = der.read();
578      if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE)      if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE)
579        throw new ASN1ParsingException("malformed TBSCertificate");        {
580            throw new IOException("malformed TBSCertificate");
581          }
582      tbsCertBytes = tbsCert.getEncoded();      tbsCertBytes = tbsCert.getEncoded();
583        debug("start TBSCertificate  len == " + tbsCert.getLength());
584    
585        // Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }
586      DERValue val = der.read();      DERValue val = der.read();
587      if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0)      if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0)
588        {        {
         // Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }  
589          version = ((BigInteger) der.read().getValue()).intValue() + 1;          version = ((BigInteger) der.read().getValue()).intValue() + 1;
590          val = der.read();          val = der.read();
591        }        }
# Line 534  public class X509Certificate extends jav Line 593  public class X509Certificate extends jav
593        {        {
594          version = 1;          version = 1;
595        }        }
596        debug("read version == " + version);
597    
598      // SerialNumber ::= INTEGER      // SerialNumber ::= INTEGER
599      serialNo = (BigInteger) val.getValue();      serialNo = (BigInteger) val.getValue();
600        debug("read serial number == " + serialNo);
601    
602      // AlgorithmIdentifier ::= SEQUENCE {      // AlgorithmIdentifier ::= SEQUENCE {
603      val = der.read();      val = der.read();
604      if (!val.isConstructed())      if (!val.isConstructed())
605        throw new ASN1ParsingException("malformed AlgorithmIdentifier");        {
606            throw new IOException("malformed AlgorithmIdentifier");
607          }
608      int certAlgLen = val.getLength();      int certAlgLen = val.getLength();
609        debug("start AlgorithmIdentifier  len == " + certAlgLen);
610      val = der.read();      val = der.read();
611    
612        //   algorithm    OBJECT IDENTIFIER,
613      algId = (OID) val.getValue();      algId = (OID) val.getValue();
614        debug("read algorithm ID == " + algId);
615    
616        //   parameters   ANY DEFINED BY algorithm OPTIONAL }
617      if (certAlgLen > val.getEncodedLength())      if (certAlgLen > val.getEncodedLength())
618        {        {
619          val = der.read();          val = der.read();
620          if (val == null)          if (val == null)
621            algVal = null;            {
622                algVal = null;
623              }
624          else          else
625            algVal = val.getEncoded();            {
626                algVal = val.getEncoded();
627              }
628          if (val.isConstructed())          if (val.isConstructed())
629            encoded.skip(val.getLength());            {
630                encoded.skip(val.getLength());
631              }
632            debug("read algorithm parameters == " + algVal);
633        }        }
634    
635      issuer = new X500Principal(encoded);      // issuer   Name,
636        val = der.read();
637        issuer = new X500DistinguishedName(val.getEncoded());
638        der.skip(val.getLength());
639        debug("read issuer == " + issuer);
640    
641        // Validity ::= SEQUENCE {
642        //   notBefore   Time,
643        //   notAfter    Time }
644      if (!der.read().isConstructed())      if (!der.read().isConstructed())
645        throw new ASN1ParsingException("malformed Validity");        {
646            throw new IOException("malformed Validity");
647          }
648      notBefore = (Date) der.read().getValue();      notBefore = (Date) der.read().getValue();
649      notAfter  = (Date) der.read().getValue();      notAfter  = (Date) der.read().getValue();
650        debug("read notBefore == " + notBefore);
651        debug("read notAfter == " + notAfter);
652    
653      subject = new X500Principal(encoded);      // subject   Name,
   
     if (!der.read().isConstructed())  
       throw new ASN1ParsingException("malformed SubjectPublicKeyInfo");  
     
     val = der.read();  
     if (!val.isConstructed())  
       throw new ASN1ParsingException("malformed AlgorithmIdentifier");  
     int keyAlgLen = val.getLength();  
654      val = der.read();      val = der.read();
655      OID keyID = (OID) val.getValue();      subject = new X500DistinguishedName(val.getEncoded());
656      byte[] keyParams = null;      der.skip(val.getLength());
657      if (keyAlgLen > val.getEncodedLength())      debug("read subject == " + subject);
658        {  
659          val = der.read();      // SubjectPublicKeyInfo ::= SEQUENCE {
660          keyParams = val.getEncoded();      //   algorithm         AlgorithmIdentifier,
661          if (algVal == null)      //   subjectPublicKey  BIT STRING }
662            algVal = keyParams;      DERValue spki = der.read();
663          if (val.isConstructed())      if (!spki.isConstructed())
664            encoded.skip(val.getLength());        {
665        }          throw new IOException("malformed SubjectPublicKeyInfo");
666      val = der.read();        }
667      byte[] keyVal = ((BitString) val.getValue()).toByteArray();      KeyFactory spkFac = KeyFactory.getInstance("X.509");
668        subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));
669        der.skip(spki.getLength());
670        debug("read subjectPublicKey == " + subjectKey);
671    
672      if (keyID.equals(ID_DSA))      if (version > 1)
673        {        {
674          AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");          val = der.read();
         params.init(keyParams, "ASN.1");  
         KeyFactory keyFac = KeyFactory.getInstance("DSA");  
         DSAParameterSpec spec = (DSAParameterSpec)  
           params.getParameterSpec(DSAParameterSpec.class);  
         subjectKey = keyFac.generatePublic(new DSAPublicKeySpec(  
           (BigInteger) new DERReader(keyVal).read().getValue(),  
           spec.getP(), spec.getQ(), spec.getG()));  
       }  
     else if (keyID.equals(ID_RSA))  
       {  
         KeyFactory keyFac = KeyFactory.getInstance("RSA");  
         DERReader rsaKey = new DERReader(keyVal);  
         if (!rsaKey.read().isConstructed())  
           throw new ASN1ParsingException("malformed RSAPublicKey");  
         subjectKey = keyFac.generatePublic(new RSAPublicKeySpec(  
           (BigInteger) rsaKey.read().getValue(),  
           (BigInteger) rsaKey.read().getValue()));  
675        }        }
     else  
       throw new ASN1ParsingException("unknown key algorithm " + keyID);  
   
     if (version > 1)  
       val = der.read();  
676      if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1)      if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1)
677        {        {
678          byte[] b = (byte[]) val.getValue();          byte[] b = (byte[]) val.getValue();
679          issuerUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);          issuerUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
680            debug("read issuerUniqueId == " + issuerUniqueId);
681          val = der.read();          val = der.read();
682        }        }
683      if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2)      if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2)
684        {        {
685          byte[] b = (byte[]) val.getValue();          byte[] b = (byte[]) val.getValue();
686          subjectUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);          subjectUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
687            debug("read subjectUniqueId == " + subjectUniqueId);
688          val = der.read();          val = der.read();
689        }        }
690      if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3)      if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3)
691        {        {
692          val = der.read();          val = der.read();
693            debug("start Extensions  len == " + val.getLength());
694          int len = 0;          int len = 0;
695          while (len < val.getLength())          while (len < val.getLength())
696            {            {
697              DERValue ext = der.read();              DERValue ext = der.read();
698              OID extId = (OID) der.read().getValue();              debug("start extension  len == " + ext.getLength());
699              DERValue val2 = der.read();              Extension e = new Extension(ext.getEncoded());
700              Boolean crit = Boolean.valueOf(false);              extensions.put(e.getOid(), e);
701              if (val2.getValue() instanceof Boolean)              der.skip(ext.getLength());
               {  
                 crit = (Boolean) val2.getValue();  
                 val2 = der.read();  
               }  
             byte[] extVal = (byte[]) val2.getValue();  
             extensions.put(extId.toString(), extVal);  
             if (crit.booleanValue())  
               critOids.add(extId.toString());  
             else  
               nonCritOids.add(extId.toString());  
             if (extId.equals(ID_KEY_USAGE))  
               {  
                 keyUsage = (BitString) DERReader.read(extVal).getValue();  
               }  
             else if (extId.equals(ID_BASIC_CONSTRAINTS))  
               {  
                 DERReader bc = new DERReader(extVal);  
                 DERValue constraints = bc.read();  
                 if (!constraints.isConstructed())  
                   throw new ASN1ParsingException("malformed BasicConstraints");  
                 if (constraints.getLength() > 0)  
                   {  
                     boolean ca = false;  
                     int constr = -1;  
                     val2 = bc.read();  
                     if (val2.getValue() instanceof Boolean)  
                       {  
                         ca = ((Boolean) val2.getValue()).booleanValue();  
                         if (constraints.getLength() > val2.getEncodedLength())  
                           val2 = bc.read();  
                       }  
                     if (val2.getValue() instanceof BigInteger)  
                       constr = ((BigInteger) val2.getValue()).intValue();  
                     basicConstraints = constr;  
                   }  
               }  
702              len += ext.getEncodedLength();              len += ext.getEncodedLength();
703                debug("count == " + len);
704            }            }
705        }        }
706    
707      val = der.read();      val = der.read();
708      if (!val.isConstructed())      if (!val.isConstructed())
709        throw new ASN1ParsingException("malformed AlgorithmIdentifier");        {
710            throw new IOException("malformed AlgorithmIdentifier");
711          }
712      int sigAlgLen = val.getLength();      int sigAlgLen = val.getLength();
713        debug("start AlgorithmIdentifier  len == " + sigAlgLen);
714      val = der.read();      val = der.read();
715      sigAlgId = (OID) val.getValue();      sigAlgId = (OID) val.getValue();
716        debug("read algorithm id == " + sigAlgId);
717      if (sigAlgLen > val.getEncodedLength())      if (sigAlgLen > val.getEncodedLength())
718        {        {
719          val = der.read();          val = der.read();
720          if (val.getValue() == null)          if (val.getValue() == null)
721            sigAlgVal = keyParams;            {
722                if (subjectKey instanceof DSAPublicKey)
723                  {
724                    AlgorithmParameters params =
725                      AlgorithmParameters.getInstance("DSA");
726                    DSAParams dsap = ((DSAPublicKey) subjectKey).getParams();
727                    DSAParameterSpec spec =
728                      new DSAParameterSpec(dsap.getP(), dsap.getQ(), dsap.getG());
729                    params.init(spec);
730                    sigAlgVal = params.getEncoded();
731                  }
732              }
733          else          else
734            sigAlgVal = (byte[]) val.getEncoded();            {
735                sigAlgVal = (byte[]) val.getEncoded();
736              }
737          if (val.isConstructed())          if (val.isConstructed())
738            encoded.skip(val.getLength());            {
739                encoded.skip(val.getLength());
740              }
741            debug("read parameters == " + sigAlgVal);
742        }        }
743      signature = ((BitString) der.read().getValue()).toByteArray();      signature = ((BitString) der.read().getValue()).toByteArray();
744        debug("read signature ==\n" + Util.hexDump(signature, ">>>> "));
745    }    }
746  }  }

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.3.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26