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);
}
}