package at.gv.egovernment.moa.spss.api.xmlbind; import java.io.IOException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import iaik.utils.RFC2253NameParser; import iaik.utils.RFC2253NameParserException; import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.spss.MOAApplicationException; import at.gv.egovernment.moa.spss.MOASystemException; /** * Utility methods used by the verious ResponseBuilder classes. * * @author Patrick Peck * @version $Id$ */ class ResponseBuilderUtils { // // shortcuts to various XML namespace constants // private static final String MOA_NS_URI = Constants.MOA_NS_URI; private static final String SL11 = Constants.SL11_PREFIX + ":"; private static final String SL11_NS_URI = Constants.SL11_NS_URI; private static final String DSIG = Constants.DSIG_PREFIX + ":"; private static final String DSIG_NS_URI = Constants.DSIG_NS_URI; private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; /** * Create a response element with all the namespaces set. * * @param responseName The name of the response root element. * @return A DOM document containing the response root element and predefined * MOA, DSIG and XML namespace declarations. * @throws MOASystemException An error building the response document. */ public static Document createResponse(String responseName) throws MOASystemException { try { DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); DOMImplementation impl = docBuilder.getDOMImplementation(); Document response; Element root; String attrValue; response = impl.createDocument(MOA_NS_URI, responseName, null); root = response.getDocumentElement(); // add namespace prefix declarations root.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); attrValue = "xmlns:" + Constants.DSIG_PREFIX; root.setAttributeNS(XMLNS_NS_URI, attrValue, DSIG_NS_URI); return response; } catch (ParserConfigurationException e) { throw new MOASystemException("2200", null, e); } } /** * Add a SignerInfo element to the response. * * @param response The response document, in order to create new elements in * it. * @param root The root element into which the SignerInfo element * will be inserted. * @param cert The signer certificate to add. * @param isQualified Indicates, whether cert is a qualified * certificate. * @param isPublicAuthority Indicates, whether cert is * certificate owned by a public authority. * @param publicAuthorityID Information about the public authority owning * cert. Must not be null, if * isPublicAuthority ! = null. * @throws MOAApplicationException An error occurred reading data from the * certificate. */ public static void addSignerInfo( Document response, Element root, X509Certificate cert, boolean isQualified, boolean isPublicAuthority, String publicAuthorityID) throws MOAApplicationException { Element signerInfoElem = response.createElementNS(MOA_NS_URI, "SignerInfo"); Element x509DataElem = response.createElementNS(DSIG_NS_URI, DSIG + "X509Data"); Element x509IssuerSerialElem = response.createElementNS(DSIG_NS_URI, DSIG + "X509IssuerSerial"); Element x509IssuerElem = response.createElementNS(DSIG_NS_URI, DSIG + "X509IssuerName"); String issuer = cert.getIssuerDN().getName(); Element x509SerialNumberElem = response.createElementNS(DSIG_NS_URI, DSIG + "X509SerialNumber"); String serialNumber = cert.getSerialNumber().toString(); Element x509SubjectNameElem = response.createElementNS(DSIG_NS_URI, DSIG + "X509SubjectName"); Element x509CertificateElem = response.createElementNS(DSIG_NS_URI, DSIG + "X509Certificate"); Element qualifiedCertificateElem = isQualified ? response.createElementNS(SL11_NS_URI, SL11 + "QualifiedCertificate") : null; Element publicAuthorityElem = isPublicAuthority ? response.createElementNS(MOA_NS_URI, "PublicAuthority") : null; Element codeElem = publicAuthorityID != null ? response.createElementNS(MOA_NS_URI, "Code") : null; // fill in text x509IssuerElem.appendChild(response.createTextNode(issuer)); x509SerialNumberElem.appendChild(response.createTextNode(serialNumber)); try { RFC2253NameParser parser = new RFC2253NameParser(cert.getSubjectDN().getName()); String subjectRfc2253 = parser.parse().getRFC2253String(); x509SubjectNameElem.appendChild(response.createTextNode(subjectRfc2253)); } catch (RFC2253NameParserException e) { x509SubjectNameElem.appendChild( response.createTextNode(cert.getSubjectDN().getName())); } try { x509CertificateElem.appendChild( response.createTextNode(Base64Utils.encode(cert.getEncoded()))); } catch (CertificateEncodingException e) { throw new MOAApplicationException("2245", null, e); } catch (IOException e) { throw new MOAApplicationException("2245", null, e); } // build structure x509DataElem.appendChild(x509SubjectNameElem); x509IssuerSerialElem.appendChild(x509IssuerElem); x509IssuerSerialElem.appendChild(x509SerialNumberElem); x509DataElem.appendChild(x509IssuerSerialElem); x509DataElem.appendChild(x509CertificateElem); if (isQualified) { String attrValue = "xmlns:" + Constants.SL11_PREFIX; qualifiedCertificateElem.setAttributeNS( XMLNS_NS_URI, attrValue, SL11_NS_URI); x509DataElem.appendChild(qualifiedCertificateElem); } if (isPublicAuthority) { x509DataElem.appendChild(publicAuthorityElem); if (publicAuthorityID != null) { codeElem.appendChild(response.createTextNode(publicAuthorityID)); publicAuthorityElem.appendChild(codeElem); } } signerInfoElem.appendChild(x509DataElem); root.appendChild(signerInfoElem); } /** * Add an element containing Code and Info * subelements. * * @param response The response document, in order to create new elements in * it. * @param root The root element into which to insert the newly created * element. * @param elementName The name of the newly created element. * @param code The content of the Code subelement. * @param info The content of the Info subelement. */ public static void addCodeInfoElement( Document response, Element root, String elementName, int code, NodeList info) { Element codeInfoElem = response.createElementNS(MOA_NS_URI, elementName); Element codeElem = response.createElementNS(MOA_NS_URI, "Code"); Element infoElem; int i; codeElem.appendChild(response.createTextNode(Integer.toString(code))); codeInfoElem.appendChild(codeElem); if (info != null) { infoElem = response.createElementNS(MOA_NS_URI, "Info"); for (i = 0; i < info.getLength(); i++) { infoElem.appendChild(info.item(i).cloneNode(true)); } codeInfoElem.appendChild(infoElem); } root.appendChild(codeInfoElem); } }