debug("read subjectPublicKey == " + subjectKey);
logger.log (Component.X509, "read subjectPublicKey == {0}", subjectKey);
  private void parse(InputStream encoded) throws Exception  {    DERReader der = new DERReader(encoded);    // Certificate ::= SEQUENCE {    DERValue cert = der.read();    debug("start Certificate  len == " + cert.getLength());    this.encoded = cert.getEncoded();    if (!cert.isConstructed())      {        throw new IOException("malformed Certificate");      }    // TBSCertificate ::= SEQUENCE {    DERValue tbsCert = der.read();    if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE)      {        throw new IOException("malformed TBSCertificate");      }    tbsCertBytes = tbsCert.getEncoded();    debug("start TBSCertificate  len == " + tbsCert.getLength());    // Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }    DERValue val = der.read();    if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0)      {        version = ((BigInteger) der.read().getValue()).intValue() + 1;        val = der.read();      }    else      {        version = 1;      }    debug("read version == " + version);    // SerialNumber ::= INTEGER    serialNo = (BigInteger) val.getValue();    debug("read serial number == " + serialNo);    // AlgorithmIdentifier ::= SEQUENCE {    val = der.read();    if (!val.isConstructed())      {        throw new IOException("malformed AlgorithmIdentifier");      }    int certAlgLen = val.getLength();    debug("start AlgorithmIdentifier  len == " + certAlgLen);    val = der.read();    //   algorithm    OBJECT IDENTIFIER,    algId = (OID) val.getValue();    debug("read algorithm ID == " + algId);    //   parameters   ANY DEFINED BY algorithm OPTIONAL }    if (certAlgLen > val.getEncodedLength())      {        val = der.read();        if (val == null)          {          algVal = null;          }        else          {          algVal = val.getEncoded();	            if (val.isConstructed())          encoded.skip(val.getLength());      }        debug("read algorithm parameters == " + algVal);      }    // issuer   Name,    val = der.read();    issuer = new X500DistinguishedName(val.getEncoded());    der.skip(val.getLength());    debug("read issuer == " + issuer);    // Validity ::= SEQUENCE {    //   notBefore   Time,    //   notAfter    Time }    if (!der.read().isConstructed())      {        throw new IOException("malformed Validity");      }    notBefore = (Date) der.read().getValue();    notAfter  = (Date) der.read().getValue();    debug("read notBefore == " + notBefore);    debug("read notAfter == " + notAfter);    // subject   Name,    val = der.read();    subject = new X500DistinguishedName(val.getEncoded());    der.skip(val.getLength());    debug("read subject == " + subject);    // SubjectPublicKeyInfo ::= SEQUENCE {    //   algorithm         AlgorithmIdentifier,    //   subjectPublicKey  BIT STRING }    DERValue spki = der.read();    if (!spki.isConstructed())      {        throw new IOException("malformed SubjectPublicKeyInfo");      }    KeyFactory spkFac = KeyFactory.getInstance("X.509");    subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));    der.skip(spki.getLength());    debug("read subjectPublicKey == " + subjectKey);    if (version > 1)      {      val = der.read();      }    if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1)      {        byte[] b = (byte[]) val.getValue();        issuerUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);        debug("read issuerUniqueId == " + issuerUniqueId);        val = der.read();      }    if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2)      {        byte[] b = (byte[]) val.getValue();        subjectUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);        debug("read subjectUniqueId == " + subjectUniqueId);        val = der.read();      }    if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3)      {        val = der.read();        debug("start Extensions  len == " + val.getLength());        int len = 0;        while (len < val.getLength())          {            DERValue ext = der.read();            debug("start extension  len == " + ext.getLength());            Extension e = new Extension(ext.getEncoded());            extensions.put(e.getOid(), e);            der.skip(ext.getLength());            len += ext.getEncodedLength();            debug("count == " + len);          }      }    val = der.read();    if (!val.isConstructed())      {        throw new IOException("malformed AlgorithmIdentifier");      }    int sigAlgLen = val.getLength();    debug("start AlgorithmIdentifier  len == " + sigAlgLen);    val = der.read();    sigAlgId = (OID) val.getValue();    debug("read algorithm id == " + sigAlgId);    if (sigAlgLen > val.getEncodedLength())      {        val = der.read();        if (val.getValue() == null)          {            if (subjectKey instanceof DSAPublicKey)              {                AlgorithmParameters params =                  AlgorithmParameters.getInstance("DSA");                DSAParams dsap = ((DSAPublicKey) subjectKey).getParams();                DSAParameterSpec spec =                  new DSAParameterSpec(dsap.getP(), dsap.getQ(), dsap.getG());                params.init(spec);                sigAlgVal = params.getEncoded();              }          }        else          {          sigAlgVal = (byte[]) val.getEncoded();          }        if (val.isConstructed())          {          encoded.skip(val.getLength());      }        debug("read parameters == " + sigAlgVal);      }    signature = ((BitString) der.read().getValue()).toByteArray();    debug("read signature ==\n" + Util.hexDump(signature, ">>>> "));  }