/* * (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.xml.asn1.SAXEventDumper; import com.ibm.xml.asn1.LabelSAX; import com.ibm.xml.parser.Parser; import com.ibm.xml.parser.DTD; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import org.apache.xerces.parsers.SAXParser; 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.DefaultHandler; /** * Sample of cascading LabelSAX *
* Usage: java asn1.LabelPKCS7 XER * where XER is unlabeled XML representation of PKCS7 data * * Limitation: * Currently only SignedData is supported. See oid2ElementName() below. * * * This program works as illustrated below. * When LabelPKCS7 see ContentInfo.content, it "switches" the event flow * the second LabelSAX that is responsible for labeling the contents. * This second LabelSAX receives the name of the root element based on * the contentType field of the outer data structure. From the application * point of view (SAXDump, in this case), the whole set up looks as if * it is yet another SAX event source. * * * ================== SAX Event Flow ===================> * * +------+ +--------+ +----------+ ContentInfo +--------+ * | SAX |-->|LabelSAX|-->|LabelPKCS7|---------------------->|SAXDump | * |parser| | #1 | | |--+ +--------+ +---->| | * +------+ +--------+ +----------+ | |LabelSAX| | +--------+ * +->| #2 |--+ * +--------+ * SignedData ** * @author Hiroshi Maruyama * @author Takeshi Imamura */ public class LabelPKCS7 extends DefaultHandler { static boolean opt_d = false; static String inf; static String dtd = "pkcs7.dtd"; static String rootElement = "root..ContentInfo"; /** * Constructs an object and initializes some variables according to * the specified arguments. * * @param
args arguments to this program.
*/
public LabelPKCS7() {
//
// Do nothing
//
}
/**
* Labels XER encoded ASN.1 data with given DTD
*
* @exception java.io.IOException -
* @exception org.xml.sax.SAXException -
*/
private void start() throws IOException, SAXException {
SAXEventDumper dump = new SAXEventDumper();
Writer out = new OutputStreamWriter(System.out);
dump.setWriter(out);
dump.setXMLDeclaration("1.0", null);
// dump.setDoctypeDeclaration(rootElement, dtd);
handler = dump;
LabelSAX lsax = new LabelSAX(this);
DTD d = readDTD(dtd);
lsax.setDTD(d, rootElement);
lsax.setEncoding("base64");
SAXParser psr = new SAXParser();
psr.setContentHandler(lsax);
psr.setErrorHandler(this);
psr.parse(inf);
}
/**
* Reads a DTD from a file.
*
* @param name the name of the file containing a DTD.
*
* @return a DTD.
*
* @exception java.io.IOException -
*/
private DTD readDTD(String name) throws IOException {
Parser psr = new Parser(name);
psr.setErrorHandler(this);
Reader in = new InputStreamReader((LabelPKCS7.class).getResourceAsStream(name));
DTD dtd = psr.readDTDStream(in);
return dtd;
}
//
// Member variables for controling filtering operations
//
StringBuffer buffer = null;
String ContentType;
ContentHandler handler;
ContentHandler handlerSave;
//
// The following five methods implements ContentHandler
//
public void startDocument() throws SAXException {
handler.startDocument();
}
public void endDocument() throws SAXException {
handler.endDocument();
}
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
try {
handler.startElement(uri, localName, name, atts);
if (name.equals("ContentInfo.contentType")) {
this.buffer = new StringBuffer();
} else if (name.equals("ContentInfo.content")) {
//
// Start processing Content
// 1. Create another LabelSAX
//
LabelSAX lsaxContents = new LabelSAX(handler);
DTD d;
d = readDTD(dtd);
lsaxContents.setDTD(d, oid2ElementName(ContentType));
lsaxContents.setEncoding("base64");
//
// 2. Redirect SAX events
//
handlerSave = handler;
handler = lsaxContents;
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public void endElement(String uri, String localName, String name) throws SAXException {
if (name.equals("ContentInfo.contentType")) {
this.ContentType = this.buffer.toString();
// System.err.println("ContentType:"+this.ContentType);
this.buffer = null;
} else if (name.equals("ContentInfo.content")) {
// Restore handler
handler = handlerSave;
}
handler.endElement(uri, localName, name);
}
public void characters(char chars[], int start, int length) throws SAXException {
handler.characters(chars,start,length);
if (this.buffer != null) {
this.buffer.append(chars, start, length);
}
}
/**
* oid2ElementName translation table
* This table should be expanded as necessary.
*/
String oid2ElementName(String oid) {
if (oid.equals("1.2.840.113549.1.7.2")) return "root..SignedData";
return "";
}
//
// The following three methods implements ErrorHandler
//
/**
* Receive notification of a warning. The warning information is
* printed.
*
* @param exc the warning information encapsulated in a
* SAX parse exception.
*/
public void warning(SAXParseException exc) {
System.err.println("[Warning] "+getLocation(exc)+": "+exc.getMessage());
}
/**
* Receive notification of a recoverable error. The error
* information is printed.
*
* @param exc the error information encapsulated in a
* SAX parse exception.
*/
public void error(SAXParseException exc) {
System.err.println("[Error] "+getLocation(exc)+": "+exc.getMessage());
}
/**
* Receive notification of a non-recoverable error. The error
* information is printed and the exception is thrown again.
*
* @param exc the error information encapsulated in a
* SAX parse exception.
*
* @exception org.xml.sax.SAXException -
*/
public void fatalError(SAXParseException exc) throws SAXException {
System.err.println("[Fatal Error] "+getLocation(exc)+": "+exc.getMessage());
throw exc;
}
/**
* Gets the location where the exception is thrown.
*
* @param exc the warning or error information
* encapsulated in a SAX parse exception.
*/
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
//
/**
* Creates this object and starts a translation.
*/
public static void main(String args[]) {
int i=0;
if (args.length<1) {
usage(-1);
} else if (args[0].equals("-d")) {
opt_d = true;
i++;
}
if (args.lengthstat a status of this program.
*/
private static void usage(int stat) {
System.err.println("Usage: java asn1.LabelPKCS7