O dispositivo de parsing está implementado simplesmente como um par de interfaces: os dispositivos efetivos deverão implementar a interface EnvelopeParser. Em vista da complexidade da árvore de objetos, imaginamos delegar a responsabilidade de efetuar o parsing de cada um deles por helpers que implementem a interface genérica ParsingHelper. A pobreza do design é devida também às radicais diferenças entre as duas implementações planejadas: CMS e XMLDSig, que têm em comum somente a semântica dos diversos componentes de cada envelope. A próxima seção ilustra o graphos de chamada do parser implementado.
Um exemplo de utilização pode ser visto a seguir. Observe-se que a implementação CMSParser capta todas as exceções disparadas por seus componentes, incluindo o BouncyCastle e as relança como uma ParserException ou uma de suas especializações. Desse modo, é aconselhável a obtenção sempre da causa da exceção com getCause().
public class TestCMSParser {
public static void listSignedFile(String file) {
TestCMSParser testCase = new TestCMSParser();
testCase.registerComponents();
FileInputStream in;
try {
in = new FileInputStream(file);
try {
ContentInfo envelope = testCase.parseEnvelope(in);
testCase.doSomething(envelope);
}
finally {
in.close();
}
}
catch (RuntimeException e) {
System.out.println("Parse error:");
e.printStackTrace();
e.getCause().printStackTrace();
}
catch (IOException e) {
System.out.println("I/O error:");
e.printStackTrace();
}
}
public static void createNewSignedFile(String file) {
TestCMSParser testCase = new TestCMSParser();
testCase.registerComponents();
FileInputStream in;
try {
in = new FileInputStream(file);
try {
ContentInfo envelope = testCase.parseEnvelope(in);
FileOutputStream out = new FileOutputStream(file + ".p7s");
try {
testCase.buildEnvelope(envelope, out);
}
finally {
out.close();
}
}
finally {
in.close();
}
}
catch (RuntimeException e) {
System.out.println("Parse error:");
e.printStackTrace();
e.getCause().printStackTrace();
}
catch (IOException e) {
System.out.println("I/O error:");
e.printStackTrace();
}
}
public void buildEnvelope(ContentInfo envelope, OutputStream out) {
EnvelopeParser parser = AbstractParser.getInstance();
parser.buildEnvelope(envelope, out);
}
public void registerComponents() {
AbstractParser.register("CMS", new CMSParser());
AbstractParser.setDefaultImplementation("CMS");
}
public ContentInfo parseEnvelope(InputStream in) {
EnvelopeParser parser = AbstractParser.getInstance();
return parser.parseEnvelope(in);
}
public void doSomething(ContentInfo envelope) {
System.out.println("Envelope content type: " + envelope.getContentType());
SignedData signedData = (SignedData) envelope.getContent();
System.out.println("Version: " + signedData.getVersion());
System.out.println("Encapsulated content info type: " + signedData.getEncapContentInfo().getContentType());
Iterator certs = signedData.getCertificates().iterator();
System.out.println("Included certificates:");
while (certs.hasNext())
System.out.println("Subject: " + certs.next().getSubjectX500Principal().getName());
Iterator crls = signedData.getCrls().iterator();
System.out.println("Included CRLs:");
while (crls.hasNext())
System.out.println("Issuer: " + crls.next().getIssuerX500Principal().getName());
Iterator signers = signedData.getSignerInfos().iterator();
System.out.println("Document signers:");
while (signers.hasNext()) {
SignerInfo signer = signers.next();
System.out.println("Version: " + signer.getVersion());
System.out.println("Signer identifier: " + signer.getSid().toString());
System.out.println("Digest algorithm: " + signer.getDigestAlgorithm().getAlgorithm());
System.out.println("Signature algorithm: " + signer.getSignatureAlgorithm().getAlgorithm());
System.out.println("Signed attributes:");
Iterator attributes = signer.getSignedAttrs().iterator();
while (attributes.hasNext())
System.out.println("OID: " + attributes.next().getAttrType());
System.out.println("Unsigned attributes: ");
attributes = signer.getUnsignedAttrs().iterator();
while (attributes.hasNext())
System.out.println("OID: " + attributes.next().getAttrType());
}
}
}