/* * (C) Copyright IBM Corp. 1999-2000 All rights reserved. * * US Government Users Restricted Rights Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * * The program is provided "as is" without any warranty express or * implied, including the warranty of non-infringement and the implied * warranties of merchantibility and fitness for a particular purpose. * IBM will not be liable for any damages suffered by you as a result * of using the Program. In no event will IBM be liable for any * special, indirect or consequential damages or lost profits even if * IBM has been advised of the possibility of their occurrence. IBM * will not be liable for any third party claims against you. */ package asn1; import com.ibm.util.Base64; import com.ibm.xml.asn1.ASN12SAX; import com.ibm.xml.asn1.LabelSAX; import com.ibm.xml.asn1.SAXEventDumper; import com.ibm.xml.parser.DTD; import com.ibm.xml.parser.Parser; import java.io.FileInputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.Reader; import java.io.Writer; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; /** * @author Takeshi IMAMURA */ public class LabelX509Cert implements ErrorHandler { private Converter conv = null; private Expander exp = null; private SAXEventDumper dump = null; private String dtdFileName = "x509.dtd"; private String dtdName = "root..Certificate"; private DTD dtd = null; public LabelX509Cert() { try { dtd = readDTD(dtdFileName); } catch (IOException e) { } dump = new SAXEventDumper(); dump.setXMLDeclaration("1.0", null); dump.setDoctypeDeclaration(dtdName, dtdFileName); exp = new Expander(dump); conv = new Converter(exp); conv.setDTD(dtd, dtdName); } private DTD readDTD(String name) throws IOException { DTD dtd = null; Parser psr = new Parser(name); psr.setErrorHandler(this); Reader in = new InputStreamReader((LabelX509Cert.class).getResourceAsStream(name)); //Reader in = new FileReader(name); dtd = psr.readDTDStream(in); return dtd; } public void start(InputStream in, Writer out) { try { dump.setWriter(out); conv.setInputStream(in); conv.start(); } catch (SAXException saxe) { Exception e = saxe.getException(); if (e == null) { e = saxe; } e.printStackTrace(); System.exit(1); } } public class Converter { private ASN12SAX a2s = null; private LabelSAX lab = null; public Converter(ContentHandler handler) { lab = new LabelSAX(handler); lab.setEncoding("base64"); a2s = new ASN12SAX(lab); } public void setByteArray(byte data[]) { a2s.setByteArray(data); } public void setInputStream(InputStream in) { a2s.setInputStream(in); } public void setPartialDecoding(boolean isPartial) { a2s.setPartialDecoding(isPartial); } public void setDTD(DTD dtd, String name) { lab.setDTD(dtd, name); } public void start() throws SAXException { a2s.start(); } public void init() { a2s.init(); lab.init(); } } public class Expander extends DefaultHandler { private ContentHandler hand = null; private StringBuffer buf = null; private OIDTable oidt = null; private String tag = null; private Converter conv = null; private String uri = null; private String lname = null; private String name = null; private Attributes atts = null; public Expander(ContentHandler hand) { this.hand = hand; } public void startDocument() throws SAXException { hand.startDocument(); } public void endDocument() throws SAXException { hand.endDocument(); } public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException { if (name.equals("Extension.extnId")) { buf = new StringBuffer(); hand.startElement(uri, localName, name, atts); } else if (name.equals("Extension.extnValue")) { buf = new StringBuffer(); this.uri = uri; lname = localName; this.name = name; this.atts = atts; } else if (name.equals("root..KeyUsage")) { buf = new StringBuffer(); this.uri = uri; lname = localName; this.name = name; this.atts = atts; } else { hand.startElement(uri, localName, name, atts); } } public void endElement(String uri, String localName, String name) throws SAXException { if (name.equals("Extension.extnId")) { String s = buf.toString(); // Extension identifier buf = null; // // OID -> Tag name // if (oidt == null) { oidt = new OIDTable(); } tag = oidt.lookup(s); hand.characters(s.toCharArray(), 0, s.length()); } else if (name.equals("Extension.extnValue")) { String s = buf.toString(); // Extension value buf = null; if (tag == null) { hand.startElement(this.uri, lname, this.name, atts); hand.characters(s.toCharArray(), 0, s.length()); } else { // // Remove "encoding" attribute // AttributesImpl aa = (AttributesImpl)atts; int i = aa.getIndex("encoding"); aa.removeAttribute(i); hand.startElement(this.uri, lname, this.name, aa); // // Expand the value // if (conv == null) { conv = new Converter(this); //conv = new Converter(dump); conv.setPartialDecoding(true); } else { conv.init(); } conv.setDTD(dtd, tag); tag = null; byte bb[] = Base64.toByteArray(s); conv.setByteArray(bb); conv.start(); } } else if (name.equals("root..KeyUsage")) { int i = Integer.parseInt(atts.getValue("length")); String s = com.ibm.xml.asn1.Base64.decodeBitString(buf.toString(), i); buf = null; // // Remove "encoding" and "length" attributes // AttributesImpl aa = (AttributesImpl)atts; i = aa.getIndex("encoding"); aa.removeAttribute(i); i = aa.getIndex("length"); aa.removeAttribute(i); hand.startElement(this.uri, lname, this.name, aa); // // Convert bits to names // s = (new KeyUsage()).toNames(s); hand.characters(s.toCharArray(), 0, s.length()); } hand.endElement(uri, localName, name); } public void characters(char chars[], int start, int length) throws SAXException { if (buf == null) { hand.characters(chars, start, length); } else { buf.append(chars, start, length); } } } public class OIDTable { private final String TAGS[] = {null, null, null, null, null, null, null, null, null, "root..SubjectDirectoryAttributes", // 9 null, null, null, null, "root..SubjectKeyIdentifier", // 14 "root..KeyUsage", // 15 "root..PrivateKeyUsagePeriod", // 16 "root..SubjectAltName", // 17 "root..IssuerAltName", // 18 "root..BasicConstraints", // 19 null, null, null, null, null, null, null, null, null, null, "root..NameConstraints", // 30 "root..CRLDistPointsSyntax", // 31 "root..CertificatePolicies", // 21 "root..PolicyMappings", // 33 null, "root..AuthorityKeyIdentifier", // 35 "root..PolicyConstraints", // 36 "root..ExtKeyUsageSyntax", // 37 null, null}; public String lookup(String oid) { String tag = null; if (oid.startsWith("2.5.29.")) { int i = Integer.parseInt(oid.substring("2.5.29.".length())); if (i > -1 && i < 40) { tag = TAGS[i]; } } return tag; } } public class KeyUsage { private final String USAGE[] = {"digitalSignature", "nonRepudiation", "keyEncipherment", "dataEncipherment", "keyAgreement", "keyCertSign", "cRLSign", "encipherOnly", "decipherOnly" }; public String toNames(String bits) { StringBuffer names = new StringBuffer(); String s = ""; for (int i = 0, j = bits.length(); i < j && i < 9; i++) { //for (int i = 0; i < 9; i++) { if (bits.charAt(i) == '1') { names.append(s+USAGE[i]); s = ","; } } return names.toString(); } } // // ErrorHandler methods // public void warning(SAXParseException exc) { System.err.println("[Warning] "+getLocation(exc)+": "+exc.getMessage()); } public void error(SAXParseException exc) { System.err.println("[Error] "+getLocation(exc)+": "+exc.getMessage()); } public void fatalError(SAXParseException exc) throws SAXException { System.err.println("[Fatal Error] "+getLocation(exc)+": "+exc.getMessage()); throw exc; } private String getLocation(SAXParseException exc) { StringBuffer buf = new StringBuffer(); String id = exc.getSystemId(); if (id != null) { int i = id.lastIndexOf('/'); if (i != -1) { id = id.substring(i+1); } if (!id.equals("")) { buf.append(id+", "); } } buf.append(exc.getLineNumber()+", "); buf.append(exc.getColumnNumber()); return buf.toString(); } // // Main method // public static void main(String args[]) { InputStream in = null; Writer out = new PrintWriter(System.out); // Default try { if (args.length > 0) { in = new FileInputStream(args[0]); if (args.length > 1) { out = new FileWriter(args[1]); } } else { throw new Exception(); } } catch (Exception e) { System.err.println("Usage: java asn1.LabelX509Cert []"); System.exit(1); } LabelX509Cert lab = new LabelX509Cert(); lab.start(in, out); } }