public String toString() { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); out.println(X509CertificateImpl.class.getName() + " {"); out.println(" TBSCertificate {"); out.println(" version = " + version + ";"); out.println(" serialNo = " + serialNo + ";"); out.println(" signature = {"); out.println(" algorithm = " + getSigAlgName() + ";"); out.print(" parameters ="); if (sigAlgVal != null) { out.println(); out.print(Util.hexDump(sigAlgVal, " ")); } else { out.println(" null;"); } out.println(" }"); out.println(" issuer = " + issuer.getName() + ";"); out.println(" validity = {"); out.println(" notBefore = " + notBefore + ";"); out.println(" notAfter = " + notAfter + ";"); out.println(" }"); out.println(" subject = " + subject.getName() + ";"); out.println(" subjectPublicKeyInfo = {"); out.println(" algorithm = " + subjectKey.getAlgorithm()); out.println(" key ="); out.print(Util.hexDump(subjectKey.getEncoded(), " ")); out.println(" };"); out.println(" issuerUniqueId = " + issuerUniqueId + ";"); out.println(" subjectUniqueId = " + subjectUniqueId + ";"); out.println(" extensions = {"); for (Iterator it = extensions.values().iterator(); it.hasNext(); ) { out.println(" " + it.next()); } out.println(" }"); out.println(" }"); out.println(" signatureAlgorithm = " + getSigAlgName() + ";"); out.println(" signatureValue ="); out.print(Util.hexDump(signature, " ")); out.println("}"); return str.toString(); }
/** * Parse a DER stream into an X.509 certificate. * * @param encoded The encoded bytes. */ 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 X500Name(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 X500Name(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, ">>>> ")); }