diff options
Diffstat (limited to 'spss.server/src/at/gv/egovernment')
227 files changed, 20165 insertions, 0 deletions
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/MOAApplicationException.java b/spss.server/src/at/gv/egovernment/moa/spss/MOAApplicationException.java new file mode 100644 index 000000000..0d7abd1d3 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/MOAApplicationException.java @@ -0,0 +1,41 @@ +package at.gv.egovernment.moa.spss; +/** + * Base class of application specific MOA exceptions. + * + * Application exceptions are exceptions that originate from application + * code (e.g. inconsistent data provided by the user, no permission to access + * certain resources, etc.) + * + * @author Patrick Peck + * @version $Id$ + */ +public class MOAApplicationException extends MOAException { + + /** + * Create a new <code>MOAApplicationException</code>. + * + * @param messageId The identifier of the message associated with this + * exception. + * @param parameters Additional message parameters. + */ + public MOAApplicationException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + /** + * Create a new <code>MOAApplicationException</code>. + * + * @param messageId The identifier of the message associated with this + * <code>MOAApplicationException</code>. + * @param parameters Additional message parameters. + * @param wrapped The exception wrapped by this + * <code>MOAApplicationException</code>. + */ + public MOAApplicationException( + String messageId, + Object[] parameters, + Throwable wrapped) { + super(messageId, parameters, wrapped); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/MOAException.java b/spss.server/src/at/gv/egovernment/moa/spss/MOAException.java new file mode 100644 index 000000000..a102d256b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/MOAException.java @@ -0,0 +1,164 @@ +package at.gv.egovernment.moa.spss; +import java.io.PrintStream; +import java.io.PrintWriter; + +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 at.gv.egovernment.moa.util.Constants; + +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * Base class of MOA specific exceptions. + * + * This class has the ability to wrap other exceptions which may be seen + * as the root cause for this exception. A similar mechanism is in place + * since JDK1.4 (see the <code>getClause()</code> method) but will not be used + * because of required compatibility with JDK1.3. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class MOAException extends Exception { + /** The message ID. */ + private String messageId; + /** The wrapped <code>Throwable</code>. */ + private Throwable wrapped; + + /** + * Create a <code>MOAException</code>. + * + * @param messageId The message ID of the message contained in the created + * <code>MOAException</code>. + * @param parameters The parameters needed to fill in the message arguments. + */ + public MOAException(String messageId, Object[] parameters) { + super(MessageProvider.getInstance().getMessage(messageId, parameters)); + this.messageId = messageId; + } + + /** + * Create a <code>MOAException</code>. + * + * @param messageId The message ID of the message contained in the created + * <code>MOAException</code>. + * @param parameters The parameters needed to fill in the message arguments. + * @param wrapped The exception wrapped by the created + * <code>MOAException</code>. + */ + public MOAException( + String messageId, + Object[] parameters, + Throwable wrapped) { + + super(MessageProvider.getInstance().getMessage(messageId, parameters)); + this.messageId = messageId; + this.wrapped = wrapped; + } + + /** + * Returns the message ID of this exception. + * + * @return The message ID as provided in the constructor. + */ + public String getMessageId() { + return messageId; + } + + /** + * Returns the exception wrapped by this <code>MOAException</code>. + * + * @return The exception wrapped by this exception. Possibly + * <code>null</code>, if none was provided at construction time. + */ + public Throwable getWrapped() { + return wrapped; + } + + /** + * Convert this <code>MOAException</code> to an <code>ErrorResponse</code> + * element from the MOA namespace. + * + * @return An <code>ErrorResponse</code> element, containing the subelements + * <code>ErrorCode</code> and <code>Info</code> required by the MOA schema. + */ + public Element toErrorResponse() { + DocumentBuilder builder; + DOMImplementation impl; + Document doc; + Element errorResponse; + Element errorCode; + Element info; + + // create a new document + try { + builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + impl = builder.getDOMImplementation(); + } catch (ParserConfigurationException e) { + return null; + } + + // build the ErrorResponse element + doc = impl.createDocument(Constants.MOA_NS_URI, "ErrorResponse", null); + errorResponse = doc.getDocumentElement(); + + // add MOA namespace declaration + errorResponse.setAttributeNS( + Constants.XMLNS_NS_URI, + "xmlns", + Constants.MOA_NS_URI); + + // build the child elements + errorCode = doc.createElementNS(Constants.MOA_NS_URI, "ErrorCode"); + errorCode.appendChild(doc.createTextNode(messageId)); + info = doc.createElementNS(Constants.MOA_NS_URI, "Info"); + info.appendChild(doc.createTextNode(getMessage())); + errorResponse.appendChild(errorCode); + errorResponse.appendChild(info); + return errorResponse; + } + + /** + * Print a stack trace of this exception to <code>System.err</code>. + * + * @see java.lang.Throwable#printStackTrace() + */ + public void printStackTrace() { + printStackTrace(System.err); + } + + /** + * Print a stack trace of this exception, including the wrapped exception. + * + * @param s The stream to write the stack trace to. + * @see java.lang.Throwable#printStackTrace(java.io.PrintStream) + */ + public void printStackTrace(PrintStream s) { + super.printStackTrace(s); + if (getWrapped() != null) { + s.print("Caused by: "); + getWrapped().printStackTrace(s); + } + } + + /** + * Print a stack trace of this exception, including the wrapped exception. + * + * @param s The stream to write the stacktrace to. + * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter) + */ + public void printStackTrace(PrintWriter s) { + super.printStackTrace(s); + if (getWrapped() != null) { + s.print("Caused by: "); + getWrapped().printStackTrace(s); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/MOASystemException.java b/spss.server/src/at/gv/egovernment/moa/spss/MOASystemException.java new file mode 100644 index 000000000..5a49b6852 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/MOASystemException.java @@ -0,0 +1,40 @@ +package at.gv.egovernment.moa.spss; +/** + * Base class of technical MOA exceptions. + * + * Technical exceptions are exceptions that originate from system failure (e.g., + * a database connection fails, a component is not available, etc.) + * + * @author Patrick Peck + * @version $Id$ + */ +public class MOASystemException extends MOAException { + + /** + * Create a new <code>MOASystemException</code>. + * + * @param messageId The identifier of the message associated with this + * exception. + * @param parameters Additional message parameters. + */ + public MOASystemException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + /** + * Create a new <code>MOASystemException</code>. + * + * @param messageId The identifier of the message associated with this + * <code>MOASystemException</code>. + * @param parameters Additional message parameters. + * @param wrapped The exception wrapped by this + * <code>MOASystemException</code>. + */ + public MOASystemException( + String messageId, + Object[] parameters, + Throwable wrapped) { + super(messageId, parameters, wrapped); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/Configurator.java b/spss.server/src/at/gv/egovernment/moa/spss/api/Configurator.java new file mode 100644 index 000000000..a0efa8924 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/Configurator.java @@ -0,0 +1,60 @@ +package at.gv.egovernment.moa.spss.api; + +import org.apache.commons.discovery.tools.DiscoverClass; + +import at.gv.egovernment.moa.spss.MOAException; + +/** + * Configures the SP/SS API. + * + * Also handles dynamic configuration updates. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class Configurator { + + /** The default implementation class. */ + private static final String DEFAULT_IMPLEMENTATION = + "at.gv.egovernment.moa.spss.server.init.ConfiguratorImpl"; + + /** The single instance of this class. */ + private static Configurator instance = null; + + public static synchronized Configurator getInstance() { + if (instance == null) { + try { + DiscoverClass discover = new DiscoverClass(); + instance = + (Configurator) discover.newInstance( + Configurator.class, + DEFAULT_IMPLEMENTATION); + } catch (Exception e) { + // this can not happen since we provide a valid default + // implementation + } + } + return instance; + } + + /** + * Initialize the SP/SS configuration. + * + * Only a single call to this method will have an effect. Use + * <code>update()</code> for reflecting changes in the configuration instead. + * + * @throws MOAException An error occurred updating the SP/SS configuration. + */ + public abstract void init() throws MOAException; + + /** + * Update the SP/SS configuration. + * + * This will only have an effect after the system has been initialized once + * using <code>init()</code>. + * + * @throws MOAException An error occurred updating the SP/SS configuration. + */ + public abstract void update() throws MOAException; + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/SPSSFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/api/SPSSFactory.java new file mode 100644 index 000000000..178a45273 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/SPSSFactory.java @@ -0,0 +1,993 @@ +package at.gv.egovernment.moa.spss.api; + +import java.io.InputStream; +import java.math.BigInteger; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import org.apache.commons.discovery.tools.DiscoverClass; + +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; +import at.gv.egovernment.moa.spss.api.common.Transform; +import at.gv.egovernment.moa.spss.api.common.X509IssuerSerial; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; +import at.gv.egovernment.moa.spss.api.common.XPathFilter; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.SignatureEnvironmentResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResultInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; + +/** + * An abstract factory for creating MOA SP/SS API objects. + * + * Use <code>getInstance()</code> to get a concrete factory instance. Using + * this instance, concrete MOA SP/SS API object can be created. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class SPSSFactory { + + /** The default implementation of this class. */ + private static final String DEFAULT_IMPLEMENTATION = + "at.gv.egovernment.moa.spss.api.impl.SPSSFactoryImpl"; + + /** The single instance of this class. */ + private static SPSSFactory instance = null; + + /** + * Returns the single instance of this class. + * + * @return The single instance of this class. + */ + public static synchronized SPSSFactory getInstance() { + if (instance == null) { + try { + DiscoverClass discover = new DiscoverClass(); + instance = + (SPSSFactory) discover.newInstance( + SPSSFactory.class, + DEFAULT_IMPLEMENTATION); + } catch (Exception e) { + // this can not happen since we provide a valid default + // implementation + } + } + return instance; + } + + // + // Factory methods for creating XML signatures + // + + /** + * Create a new <code>CreateXMLSignatureRequest</code> object. + * + * @param keyIdentifier The identifier for the key group to use for signing. + * @param singleSignatureInfos A <code>List</code> of + * <code>SingleSignatureInfo</code> objects containing information about a + * single signature to be created. + * @return The <code>CreateXMLSignatureRequest</code> containing the above + * data. + * + * @pre keyIdentifier != null && keyIdentifier.length() > 0 + * @pre singleSignatureInfos != null + * @pre forall Object o in singleSignatureInfos | + * o instanceof at.gv.egovernment.moa.spss.api.common.SingleSignatureInfo + * @post return != null + */ + public abstract CreateXMLSignatureRequest createCreateXMLSignatureRequest( + String keyIdentifier, + List singleSignatureInfos); + + /** + * Create a new <code>SingleSignatureInfo</code> object. + * + * @param dataObjectInfos The data objects that will be signed (including + * transformations). + * @param createSignatureInfo Information about the signature environment. May + * be <code>null</code>. + * @param securityLayerConform If <code>true</code>, a Security Layer conform + * signature manifest is created, otherwise not. + * @return The <code>SingleSignatureInfo</code> containing the above data. + * + * @pre dataObjectInfos != null && dataObjectInfos.size() > 0 + * @pre forall Object o in dataObjectInfos | + * o instanceof at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo + * @post return != null + */ + public abstract SingleSignatureInfo createSingleSignatureInfo( + List dataObjectInfos, + CreateSignatureInfo createSignatureInfo, boolean securityLayerConform); + + /** + * Create a new <code>DataObjectInfo</code> object. + * + * @param structure The type of signature to create. + * @param childOfManifest If <code>true</code>, references will be returned + * as children of an XMLDsig manifest. Otherwise, they will be returned as + * children of the signature itself. + * @param dataObject The data object that will be signed. + * @param createTransformsInfoProfile Additional transformations to apply + * to the data object. + * @return The <code>DataObjectInfo</code> containing the above data. + * + * @pre DataObjectInfo.STRUCTURE_DETACHED.equals(structure) || + * DataObjectInfo.STRUCTURE_ENVELOPING.equals(structure) + * @pre dataObject != null + * @pre createTransformsInfoProfile != null + * @post return != null + */ + public abstract DataObjectInfo createDataObjectInfo( + String structure, + boolean childOfManifest, + Content dataObject, + CreateTransformsInfoProfile createTransformsInfoProfile); + + /** + * Create a new <code>CreateTransformsInfoProfile</code> object containing a + * reference to a locally stored profile. + * + * @param profileID The profile ID to resolve during signature creation. + * @return The <code>CreateTransformsInfoProfile</code> containing the given + * profile ID. + * + * @pre profileID != null && profileID.length() > 0 + * @post return != null + */ + public abstract CreateTransformsInfoProfile createCreateTransformsInfoProfile(String profileID); + + /** + * Create a new <code>CreateTransformsInfoProfile</code> object by providing + * the profile data explicitly. + * + * @param transformsInfo The transformations to apply to the associated + * data object. + * @param supplements Supplemental information for the transformation. May be + * <code>null</code>. + * @return The <code>CreateTransformsInfoProfile</code> containing the above + * data. + * + * @pre transformsInfo != null + * @pre supplements != null implies + * forall Object o in supplements | + * o instanceof at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation + * @post return != null + */ + public abstract CreateTransformsInfoProfile createCreateTransformsInfoProfile( + CreateTransformsInfo transformsInfo, + List supplements); + + /** + * Create a new <code>CreateTransformsInfo</code> object. + * + * @param transforms The <code>Transform</code>s to apply to the associated + * data object. May be <code>null</code>. + * @param finalDataMetaInfo Information about the type of the transformed + * data. + * @return The <code>CreateTransformsInfo</code> containing the above data. + * + * @pre transforms != null implies transforms.size > 0 + * @pre transforms != null implies + * forall Object o in transforms | + * o instanceof at.gv.egovernment.moa.spss.api.common.Transform + * @pre finalDataMetaInfo != null + * @post return != null + */ + public abstract CreateTransformsInfo createCreateTransformsInfo( + List transforms, + MetaInfo finalDataMetaInfo); + + /** + * Create a new <code>CreateSignatureInfo</code> object. + * + * @param createSignatureEnvironment The signature environment that will + * contain the signature. + * @param createSignatureEnvironmentProfile Additional information about + * the signture environment. + * @return The <code>CreateSignatureInfo</code> containing the above data. + * + * @pre createSignatureEnvironment != null + * @pre createSignatureEnvironmentProfile != null + * @post return != null + */ + public abstract CreateSignatureInfo createCreateSignatureInfo( + Content createSignatureEnvironment, + CreateSignatureEnvironmentProfile createSignatureEnvironmentProfile); + + /** + * Create a new <code>CreateSignatureEnvironmentProfile</code> object + * containing a reference to a locally stored profile. + * + * @param profileID The profile ID to resolve during signature creation. + * @return The <code>CreateSignatureEnvironmentProfile</code> containing + * the given profile ID. + * + * @pre profileID != null && profileID.length() > 0 + * @post return != null + */ + public abstract CreateSignatureEnvironmentProfile createCreateSignatureEnvironmentProfile(String profileID); + + /** + * Create a new <code>CreateSignatureEnvironmentProfile</code> object by + * providing the profile data explicitly. + * + * @param createSignatureLocation The location where the signature will be + * inserted. + * @param supplements Additional information about the signature environment. + * @return The <code>CreateSignatureEnvironmentProfile</code> containing the + * above data. + * + * @pre createSignatureLocation != null + * @pre supplements != null + * @pre forall Object o in supplements | + * o instanceof at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation + * @post return != null + */ + public abstract CreateSignatureEnvironmentProfile createCreateSignatureEnvironmentProfile( + CreateSignatureLocation createSignatureLocation, + List supplements); + + /** + * Create a new <code>CreateSignatureLocation</code> object. + * + * @param xPathExpression The XPath expression to select the signature + * parent element within the signature environment. + * @param index The index of the node, after which the signature will be + * inserted. + * @param namespaceDeclarations The namespace prefix to URI mapping to apply + * while evaluating the XPath expression. + * @return The <code>CreateSignatureLocation</code> containing the above data. + * + * @pre xPathExpression != null + * @pre index >= 0 + * @pre namespaceDeclarations != null + */ + public abstract CreateSignatureLocation createCreateSignatureLocation( + String xPathExpression, + int index, + Map namespaceDeclarations); + + /** + * Create a new <code>CreateXMLSignatureResponse</code> object. + * + * @param responseElements The elements of the response, either + * <code>SignatureEnvironmentResponse</code> objects, or + * <code>ErrorResponse</code> objects. + * @return The new <code>CreateXMLSignatureResponse</code> containing the + * above data. + * + * @pre responseElements != null && responseElements.size() > 0 + * @pre forall Object o in responseElements | + * o instanceof at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureResponseElement + * @post return != null + */ + public abstract CreateXMLSignatureResponse createCreateXMLSignatureResponse(List responseElements); + + /** + * Create a new <code>SignatureEnvironmentResponse</code> object. + * + * @param signatureEnvironment The signature environment containing the + * signature. + * @return The <code>SignatureEnvironmentResponse</code> containing the + * <code>signatureEnvironment</code>. + * + * @pre signatureEnvironment != null + * @post return != null + */ + public abstract SignatureEnvironmentResponse createSignatureEnvironmentResponse(Element signatureEnvironment); + + /** + * Create a new <code>ErrorResponse</code> object. + * + * @param code The numerical error code. + * @param info Verbose error information. + * @return The new <code>ErrorResponse</code> containing the above data. + * + * @pre code > 0 + * @pre info != null + * @post return != null + */ + public abstract ErrorResponse createErrorResponse(int code, String info); + + // + // Factory methods for verifying CMS signatures + // + + /** + * Create a new <code>VerifyCMSSignatureRequest</code> object. + * + * @param signatories The indexes of the signatories whose signature is to + * be verified. + * @param dateTime The date for which the verification is to be performed. + * May be <code>null</code>. + * @param cmsSignature The CMS signature. + * @param dataObject The signed data. May be <code>null</code>. + * @param trustProfileID The ID of the trust profile containing the trusted + * root certificates. + * @return The <code>VerifyCMSSignatureRequest</code> containing the above + * data. + * + * @pre signatories != null && signatories.length > 0 + * @pre signaturies != VerifyCMSSignatureRequest.ALL_SIGNATORIES implies + * for (int i = 0; i < signatories.length; i++) + * signatories[i] >= 1 + * @pre cmsSignature != null + * @pre trustProfileID != null && trustProfileID.length() > 0 + * @post return != null + */ + public abstract VerifyCMSSignatureRequest createVerifyCMSSignatureRequest( + int[] signatories, + Date dateTime, + InputStream cmsSignature, + CMSDataObject dataObject, + String trustProfileID); + + /** + * Create a new <code>CMSDataObject</code> object from data at a given URI. + * + * @param metaInfo Type information about the <code>CMSDataObject</code>. + * May be <code>null</code>. + * @param content The CMS content containing the data. + * @return The new <code>CMSDataObject</code> containing the data. + * + * @pre referenceURI != null + * @pre content != null + * @post return != null + */ + public abstract CMSDataObject createCMSDataObject( + MetaInfo metaInfo, + CMSContent content); + + /** + * Create a new <code>CMSContent</code> object from the data contained at the + * given URI. + * + * @param referenceURI The URI identifying the data. Must be resolvable. + * @return The <code>CMSContent</code> containing a reference to the signed + * data. + * + * @pre referenceURI != null + * @post return != null + */ + public abstract CMSContent createCMSContent(String referenceURI); + + /** + * Create a new <code>CMSContent</code> object from a byte stream. + * + * @param binaryContent The byte stream containing the signed data. + * @return The new <code>CMSContent</code> containing the data from the + * byte stream. + * + * @pre binaryContent != null + * @post return != null + */ + public abstract CMSContent createCMSContent(InputStream binaryContent); + + /** + * Create a new <code>VerifyCMSSignatureResponse</code> object. + * + * @param responseElements Verification information about each signature. + * @return The new <code>VerifyCMSSignatureResponse</code> containing the + * status of signature verification for each signature contained in the + * request. + * + * @pre responseElements != null && responseElements.size() > 0 + * @pre forall Object o in responseElements | + * o instanceof at.gv.egovernment.moa.spss.api.cmssign.VerifyCMSSignatureResponseElement + * @post return != null + */ + public abstract VerifyCMSSignatureResponse createVerifyCMSSignatureResponse(List responseElements); + + /** + * Create a new <code>VerifyCMSSignatureResponseElement</code> object. + * + * @param signerInfo Information about the signer certificate. + * @param signatureCheck Result of the singature value check. + * @param certificateCheck Result of the certificate status check. + * @return The new <code>VerifyCMSSignatureResponseElement</code> containing + * the above data. + * + * @pre signerInfo != null && signatureCheck != null && + * certificateCheck != null + * @post return != null + */ + public abstract VerifyCMSSignatureResponseElement createVerifyCMSSignatureResponseElement( + SignerInfo signerInfo, + CheckResult signatureCheck, + CheckResult certificateCheck); + + // + // Factory methods for verifying XML signatures + // + + /** + * Create a new <code>VerifyXMLSignatureRequest</code> object. + * + * @param dateTime The date for which the verification is to be performed. + * May be <code>null</code>. + * @param verifySignatureInfo Information about the signature environment and + * the location of the signature. + * @param supplementProfiles Supplemental information for the signature + * environment. May be <code>null</code>. + * @param signatureManifestParams Additional information for checking the + * signature manifest. May be <code>null</code>. + * @param returnHashInputData If <code>true</code>, hash input data will + * be returned in the response, otherwise not. + * @param trustProfileID The ID of the trust profile containing the trusted + * root certificates. + * @return The new <code>VerifyXMLSignatureRequest</code> containing the + * above data. + * + * @pre verifySignatureInfo != null + * @pre supplementProfiles != null implies + * forall Object o in supplementProfiles | + * o instanceof at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile + * @pre trustProfileID != null && trustProfileID.length() > 0 + * @post return != null + */ + public abstract VerifyXMLSignatureRequest createVerifyXMLSignatureRequest( + Date dateTime, + VerifySignatureInfo verifySignatureInfo, + List supplementProfiles, + SignatureManifestCheckParams signatureManifestParams, + boolean returnHashInputData, + String trustProfileID); + + /** + * Create a new <code>VerifySignatureInfo</code> object. + * + * @param verifySignatureEnvironment The signature environment containing + * the signature to be verified. + * @param verifySignatureLocation The location of the signature within the + * signature environment. + * @return The new <code>VerifySignatureInfo</code> containing the above data. + * + * @pre verifySignatureEnvironment != null + * @pre verifySignatureLocation != null + * @post return != null + */ + public abstract VerifySignatureInfo createVerifySignatureInfo( + Content verifySignatureEnvironment, + VerifySignatureLocation verifySignatureLocation); + + /** + * Create a new <code>VerifySignatureLocation</code> object. + * + * @param xPathExpression The XPath expression to select the signature + * element within the signature environment. + * @param namespaceDeclarations The namespace prefix to URI mapping to apply + * while evaluating the XPath expression. + * @return The new <code>VerifySignatureLocation</code> containing the above + * data. + * + * @pre xPathExpression != null + * @pre namespaceDeclarations != null + * @post return != null + */ + public abstract VerifySignatureLocation createVerifySignatureLocation( + String xPathExpression, + Map namespaceDeclarations); + + /** + * Create a new <code>SupplementProfile</code> object containing a reference + * to a locally stored profile. + * + * @param profileID The profile ID to resolve during signature verification. + * @return The <code>SupplementProfile</code> containing the profile ID. + * + * @pre profileID != null && profileID.length() > 0 + * @post return != null + */ + public abstract SupplementProfile createSupplementProfile(String profileID); + + /** + * Create a new <code>SupplementProfile</code> object by providing the profile + * data explicitly. + * + * @param supplementProfile The profile data. + * @return The <code>SupplementProfile</code> containing the profile data. + */ + public abstract SupplementProfile createSupplementProfile(XMLDataObjectAssociation supplementProfile); + + /** + * Create a new <code>SignatureManifestCheckParams</code> object. + * + * @param referenceInfos Information for checking the validity of a + * a reference. + * @param returnReferenceInputData If <code>true</code>, the input data to + * the calculation of reference digest values will be returned in the + * response, otherwise not. + * @return The <code>SignatureManifestCheckParams</code> containing the + * above data. + * + * @pre referenceInfos != null && referenceInfos.size() > 0 + * @pre forall Object o in referenceInfos | + * o instanceof at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo + * @post return != null + */ + public abstract SignatureManifestCheckParams createSignatureManifestCheckParams( + List referenceInfos, + boolean returnReferenceInputData); + + /** + * Create a new <code>ReferenceInfo</code> object. + * + * @param verifyTransformsInfoProfiles The transformation profiles valid for + * the associated reference. + * @return The <code>ReferenceInfo</code> containing the transformation + * profiles. + * + * @pre verifyTransformsInfoProfiles != null && + * verifyTransformsInfoProfiles.size() > 0 + * @pre forall Object o in verifyTransformsInfoProfiles | + * o instanceof at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile + * @post return != null + */ + public abstract ReferenceInfo createReferenceInfo(List verifyTransformsInfoProfiles); + + /** + * Create a new <code>VerifyTransformsInfoProfile</code> object containing + * a reference to a locally stored profile. + * + * @param profileID The profile ID to resolve during signature verification. + * @return The <code>VerifyTransformsInfoProfile</code> containing the + * given profile ID. + * + * @pre profileID != null && profileID.length() > 0 + * @post return != null + */ + public abstract VerifyTransformsInfoProfile createVerifyTransformsInfoProfile(String profileID); + + /** + * Create a new <code>VerifyTransformsInfoProfile</code> object by providing + * the profile data explicitly. + * + * @param transforms A valid chain of transformations for the reference. + * May be <code>null</code>. + * @param transformParameters Additional transformation information. + * @return The <code>VerifyTransformsInfoProfile</code> containing the above + * data. + * + * @pre transforms != null implies + * (transforms.size() > 0 && + * forall Object o in transforms | o instanceof Transform) + * @pre transformParameters != null implies + * forall Object o in transformParameters | + * o instanceof at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter + * @post return != null + */ + public abstract VerifyTransformsInfoProfile createVerifyTransformsInfoProfile( + List transforms, + List transformParameters); + + /** + * Create a new <code>TransformParameter</code> object with the data + * contained at the given URI. + * + * @param URI The URI identifying the data. The URI will be resolved during + * signature verification. + * @return The <code>TransformParameter</code> containing the URI of the + * data. + * + * @pre URI != null + * @post return != null + */ + public abstract TransformParameter createTransformParameter(String URI); + + /** + * Creata a new <code>TransformParameter</code> object containing the + * binary data. + * + * @param URI The URI identifying the data. + * @param binaryData The binary data. + * @return The <code>TransformParameter</code> containig the binary data. + * + * @pre URI != null + * @pre binary != null + * @post return != null + */ + public abstract TransformParameter createTransformParameter( + String URI, + InputStream binaryData); + + /** + * Create a new <code>TransformParameter</code> object containing the hash + * value of the transformation data. + * + * @param URI The URI identifying the data. It will be resolved during + * signature verification. + * @param digestMethod The digest method used for calculating the digest + * value. + * @param digestValue The hash value of the transformation data. + * @return The <code>TransformParameter</code> containing the above data. + * + * @pre URI != null + * @pre digestMethod != null + * @pre digestValue != null + */ + public abstract TransformParameter createTransformParameter( + String URI, + String digestMethod, + byte[] digestValue); + + /** + * Create a new <code>VerifyXMLSignatureResponse</code> object. + * + * @param signerInfo Information about the signer certificate. + * @param hashInputDatas The signed data objects. May be <code>null</code>. + * @param referenceInputDatas The reference input data objects. + * May be <code>null</code>. + * @param signatureCheck Status information about the signature check. + * @param signatureManifestCheck Status information about the signature + * manifest check. + * @param xmlDsigManifestChecks Status information about each XMLDsig manifest + * check. + * @param certificateCheck Status information about the signer certificate + * check. + * @return The <code>VerifyXMLSignatureResponse</code> containing the above + * data. + * + * @pre signerInfo != null + * @pre hashInputDatas != null implies + * forall Object o in hashInputDatas | + * o instanceof at.gv.egovernment.moa.spss.api.common.Content + * @pre referenceInputDatas != null implies + * forall Object o in referenceInputDatas | + * o instanceof at.gv.egovernment.moa.spss.api.common.Content + * @pre signatureCheck != null + * @pre xmlDsigManifestChecks != null implies + * forall Object o in xmlDsigManifestChecks | + * o instanceof at.gv.egovernment.moa.spss.api.xmlverifyManifestRefsCheckResult + * @pre certificateCheck != null + * @post return != null + */ + public abstract VerifyXMLSignatureResponse createVerifyXMLSignatureResponse( + SignerInfo signerInfo, + List hashInputDatas, + List referenceInputDatas, + ReferencesCheckResult signatureCheck, + ReferencesCheckResult signatureManifestCheck, + List xmlDsigManifestChecks, + CheckResult certificateCheck); + + /** + * Create a new <code>ReferencesCheckResult</code> object. + * + * @param code The status code. + * @param info Additional information about the reference check. + * @return The <code>ReferencesCheckResult</code> containing the above data. + * + * @pre code >= 0 + * @post return != null + */ + public abstract ReferencesCheckResult createReferencesCheckResult( + int code, + ReferencesCheckResultInfo info); + + /** + * Create a new <code>ReferencesCheckResultInfo</code> object. + * + * @param anyOtherInfo Arbitrary XML content describing the check result. + * May be <code>null</code>. + * @param failedReferences The indexes of the failed references. May be + * <code>null</code>. + * @return The <code>ReferencesCheckResultInfo</code> containing the above + * data. + * + * @post return != null + */ + public abstract ReferencesCheckResultInfo createReferencesCheckResultInfo( + NodeList anyOtherInfo, + int[] failedReferences); + + /** + * Create a new <code>ManifestRefsCheckResult</code> object. + * + * @param code The status code. + * @param info Additional information about the manifest check. May be + * <code>null</code>. + * @return The <code>ManifestRefsCheckResult</code> containing the above + * data. + * + * @pre code >= 0 + * @post return != null + */ + public abstract ManifestRefsCheckResult createManifestRefsCheckResult( + int code, + ManifestRefsCheckResultInfo info); + + /** + * Create a new <code>ManifestRefsCheckResultInfo</code> object. + * + * @param anyOtherInfo Arbitrary XML content describing the check result. + * May be <code>null</code>. + * @param failedReferences The indexes of the failed references. May be + * <code>null</code>. + * @param referringSigReference The index of the reference in the signature. + * @return The <code>ManifestRefsCheckResultInfo</code> containing the + * above data. + * + * @pre referringSigReference > 0 + * @post return != null + */ + public abstract ManifestRefsCheckResultInfo createManifestRefsCheckResultInfo( + NodeList anyOtherInfo, + int[] failedReferences, + int referringSigReference); + + // + // Factory methods for common objects + // + + /** + * Create a new <code>Content</code> object referencing data via a URI. + * + * @param referenceURI The URI pointing to the content. + * @return The <code>Content</code> object containing the reference. + * + * @pre referenceURI != null && referenceURI.length() > 0 + * @post return != null + */ + public abstract Content createContent(String referenceURI); + + /** + * Create a new <code>Content</code> object containing binary data. + * + * @param binaryData An <code>InputStream</code> containing the binary data. + * @param referenceURI An URI identifying the data. May be <code>null</code>. + * @return The <code>Content</code> object containing the data. + * + * @pre binaryData != null + * @post return != null + */ + public abstract Content createContent( + InputStream binaryData, + String referenceURI); + + /** + * Create a new <code>Content</code> object containing XML data. + * + * @param xmlData The XML data contained in the new <code>Content</code>. + * @param referenceURI An URI identifying the data. May be <code>null</code>. + * @return The <code>Content</code> object containing the data. + * + * @pre xmlData != null + * @post return != null + */ + public abstract Content createContent(NodeList xmlData, String referenceURI); + + /** + * Create a new <code>XMLDataObjectAssociation</code> object. + * + * @param metaInfo Information about the content type. May be + * <code>null</code>. + * @param content The <code>Content</code> object containing the data. + * @return The <code>XMLDataObjectAssociation</code> containing the above + * data. + * + * @pre content != null + * @pre content.getContentType() == Content.CONTENT_XML || + * content.getContentType() == Contetn.CONTENT_BINARY + * @pre content.getReference() != null + * @post return != null + */ + public abstract XMLDataObjectAssociation createXMLDataObjectAssociation( + MetaInfo metaInfo, + Content content); + + /** + * Create a new <code>MetaInfo</code> object. + * + * @param mimeType The MIME type part of the meta information. + * @param description Descriptive meta information. May be <code>null</code>. + * @param otherInfo XML meta information. May be <code>null</code>. + * @return The <code>MetaInfo</code> object containing the above data. + * + * @pre mimeType != null && mimeType.length() > 0 + * @pre otherInfo != null implies + * forall Node n in otherInfo | n.getNodeType() == Node.ELEMENT + */ + public abstract MetaInfo createMetaInfo( + String mimeType, + String description, + NodeList otherInfo); + + /** + * Create a <code>CanonicalizationTransform</code> type of <code>Transform</code>. + * + * @param algorithmURI The algorithm URI of the canonicalization. + * @return The created <code>CanonicalizationTransform</code> object. + * + * @pre CanonicalizationTransform.CANONICAL_XML.equals(algorithmURI) || + * CanonicalizationTransform.CANONICAL_XML_WITH_COMMENTS.equals(algorithmURI) + * @post return != null + */ + public abstract Transform createCanonicalizationTransform(String algorithmURI); + + /** + * Create an <code>ExclusiveCanonicalizationTransform</code> type of + * <code>Transform</code>. + * + * @param algorithmURI The algorithm URI of the exclusive canonicalization. + * @param inclusiveNamespacePrefixes The prefixes of the namespaces to + * treat according to canonical XML. + * @return The new <code>ExclusiveCanonicalizationTransform</code> + * + * @pre ExclusiveCanonicalizationTransform.EXCLUSIVE_CANONICAL_XML.equals(algorithmURI) || + * ExclusiveCanonicalizationTransform.EXCLUSIVE_CANONICAL_XML_WITH_COMMENTS.equals(algorithmURI) + * @pre inclusiveNamespacePrefixes != null + * @pre forall Object o in inclusiveNamespacePrefixes | o instanceof String + * @post return != null + */ + public abstract Transform createExclusiveCanonicalizationTransform( + String algorithmURI, + List inclusiveNamespacePrefixes); + + /** + * Create a <code>Base64Transform</code> type of <code>Transform</code>. + * + * @return A <code>Transform</code> denoting a Base64 decoding. + * + * @post return != null + */ + public abstract Transform createBase64Transform(); + + /** + * Create a <code>EnvelopedSignatureTransform</code> type of + * <code>Transform</code>. + * + * @return A <code>Transform</code> denoting an enveloped signature. + * + * @post return != null + */ + public abstract Transform createEnvelopedSignatureTransform(); + + /** + * Create an <code>XSLTTransform</code> type of <code>Transform</code>. + * + * @param styleSheet The XSLT stylesheet contained in the + * <code>Transform</code>. + * @return A <code>Transform</code> containing the XSLT stylesheet. + * + * @post return != null + */ + public abstract Transform createXSLTTransform(Element styleSheet); + + /** + * Create an <code>XPathTransform</code> type of <code>Transform</code>. + * + * @param xPathExpression The XPath expression to use in the created + * <code>Transform</code>. + * @param namespaceDeclarations The namespace prefix to URI mapping to + * apply on evaluation of the XPath expression. + * @return The <code>XPathTransform</code> containing the above data. + * + * @pre xPathExpression != null + * @pre namespaceDeclarations != null + * @post return != null + */ + public abstract Transform createXPathTransform( + String xPathExpression, + Map namespaceDeclarations); + + /** + * Create a new <code>XPathFilter2Transform</code> type of + * <code>Transform</code>. + * + * @param xPathFilters The filters contained in the newly created + * <code>XPathFilter2Transform</code>. + * @return The <code>XPathFilter2Transform</code> containing the given + * filters. + * + * @pre xPathFilters != null && + * forall Object o in xPathFilters | + * o instanceof at.gv.egovernment.moa.spss.api.common.XPathFilter + * @post return != null + */ + public abstract Transform createXPathFilter2Transform(List xPathFilters); + + /** + * Create a new <code>XPathFilter</code> object. + * + * @param filterType The type of filter. + * @param xPathExpression The XPath expression contained in this filter. + * @param namespaceDeclarations The namespace prefix to URI mapping to apply + * on evaluation of the XPath expression. + * @return The <code>XPathFilter</code> containing the above data. + * + * @pre XPathFilter.SUBTRACT_TYPE.equals(filterType) || + * XPathFilter.INTERSECT_TYPE.equals(filterType) || + * XPathFilter.UNION_TYPE.equals(filterType) + * @pre xPathExpression != null + * @pre namespaceDeclarations != null + * @post return != null + */ + public abstract XPathFilter createXPathFilter( + String filterType, + String xPathExpression, + Map namespaceDeclarations); + + /** + * Create a new <code>CheckResult</code> object. + * + * @param code The check code. + * @param info Verbose information about the check. May be <code>null</code>. + * @return The <code>CheckResult</code> containing the above data. + * + * @pre code >= 0 + * @post return != null + */ + public abstract CheckResult createCheckResult(int code, NodeList info); + + /** + * Create a new <code>SignerInfo</code> object. + * + * @param signerCertificate The signer certificate in binary form. + * @param qualifiedCertificate <code>true</code>, if the signer certificate is + * a qualified certificate, otherwise <code>false</code>. + * @param publicAuthority <code>true</code>, if the signer certificate is a + * public authority certificate, otherwise <code>false</code>. + * @param publicAuthorityID The identification of the public authority + * (if <code>publicAuthority</code> is <code>true</code>). May be + * <code>null</code>. + * @return The <code>SignerInfo</code> containing the above data. + * + * @pre signerCertSubjectName != null + * @pre signerCertIssuerSerial != null + * @pre signerCertificate != null + */ + public abstract SignerInfo createSignerInfo( + X509Certificate signerCertificate, + boolean qualifiedCertificate, + boolean publicAuthority, + String publicAuthorityID); + + /** + * Create a new <code>X509IssuerSerial</code> object. + * + * @param issuerName The distinguished name of the issuer. + * @param issuerSerial The certificate serial number. + * @return The <code>X509IssuerSerial</code> containing the above data. + * + * @pre issuerName != null + * @pre issuerSerial != null + */ + public abstract X509IssuerSerial createX509IssuerSerial( + String issuerName, + BigInteger issuerSerial); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/SignatureCreationService.java b/spss.server/src/at/gv/egovernment/moa/spss/api/SignatureCreationService.java new file mode 100644 index 000000000..a84ca2a83 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/SignatureCreationService.java @@ -0,0 +1,57 @@ +package at.gv.egovernment.moa.spss.api; + +import at.gv.egovernment.moa.spss.MOAException; + +import org.apache.commons.discovery.tools.DiscoverClass; + + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; + +/** + * Interface providing functions for signature creation. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class SignatureCreationService { + + /** The default implementation class. */ + private static final String DEFAULT_IMPLEMENTATION = + "at.gv.egovernment.moa.spss.server.invoke.SignatureCreationServiceImpl"; + + /** The single instance of this class. */ + private static SignatureCreationService instance = null; + + /** + * Get an instance of the <code>SignatureCreationService</code>. + * + * @return A concrete instance of the <code>SignatureCreationService</code>. + */ + public static synchronized SignatureCreationService getInstance() { + if (instance == null) { + try { + DiscoverClass discover = new DiscoverClass(); + instance = + (SignatureCreationService) discover.newInstance( + SignatureCreationService.class, + DEFAULT_IMPLEMENTATION); + } catch (Exception e) { + // this can not happen since we provide a valid default + // implementation + } + } + return instance; + } + + /** + * Create an XML signature. + * + * @param request Information on how to create the signature. + * @return A <code>CreateXMLSignatureResponse</code> containing the + * signature. + * @throws MOAException Error in server side MOA module. + */ + public abstract CreateXMLSignatureResponse createXMLSignature(CreateXMLSignatureRequest request) + throws MOAException; +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/SignatureVerificationService.java b/spss.server/src/at/gv/egovernment/moa/spss/api/SignatureVerificationService.java new file mode 100644 index 000000000..d0fcb029a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/SignatureVerificationService.java @@ -0,0 +1,69 @@ +package at.gv.egovernment.moa.spss.api; + +import org.apache.commons.discovery.tools.DiscoverClass; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; + +/** + * Interface providing functions for verifying signatures. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class SignatureVerificationService { + + /** The default implementation class. */ + private static final String DEFAULT_IMPLEMENTATION = + "at.gv.egovernment.moa.spss.server.invoke.SignatureVerificationServiceImpl"; + + /** The single instance of this class. */ + private static SignatureVerificationService instance = null; + + /** + * Get an instance of the <code>SignatureVerificationService</code>. + * + * @return A concrete instance of the + * <code>SignatureVerificationService</code>. + */ + public static synchronized SignatureVerificationService getInstance() { + if (instance == null) { + try { + DiscoverClass discover = new DiscoverClass(); + instance = + (SignatureVerificationService) discover.newInstance( + SignatureVerificationService.class, + DEFAULT_IMPLEMENTATION); + } catch (Exception e) { + // this can not happen since we provide a valid default + // implementation + } + } + return instance; + } + + /** + * Verify a CMS signature. + * + * @param request Detailed information on the verification that should be + * performed. + * @return A <code>VerifyCMSSignatureResponse</code> object that contains + * information about the performed verification. + * @throws MOAException Error in server side MOA module. + */ + public abstract VerifyCMSSignatureResponse verifyCMSSignature(VerifyCMSSignatureRequest request) + throws MOAException; + /** + * Verfiy an XML Signature. + * + * @param request information on the verification that should be performed. + * @return A <code>VerifyXMLSignatureResponse</code> object that contains + * information about the performed verification. + * @throws MOAException Error in server side MOA module. + */ + public abstract VerifyXMLSignatureResponse verifyXMLSignature(VerifyXMLSignatureRequest request) + throws MOAException; +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContent.java b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContent.java new file mode 100644 index 000000000..b4ecb3937 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContent.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.spss.api.cmsverify; + +/** + * Base class for objects containing CMS content. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CMSContent { + /** + * Indicates that this object contains a reference to the CMS content. + */ + public static final int REFERENCE_CONTENT = 0; + /** + * Indicates that this object contains the CMS content explicitly. + */ + public static final int EXPLICIT_CONTENT = 1; + + /** + * Gets the type of the contained content. + * + * @return The type of content, either <code>REFERENCE_CONTENT</code> or + * <code>EXPLICIT_CONTENT</code>. + */ + public int getContentType(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContentExcplicit.java b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContentExcplicit.java new file mode 100644 index 000000000..58c2b0259 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContentExcplicit.java @@ -0,0 +1,19 @@ +package at.gv.egovernment.moa.spss.api.cmsverify; + +import java.io.InputStream; + +/** + * Encapsulates binary CMS content. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CMSContentExcplicit extends CMSContent { + /** + * Gets the content as a stream. + * + * @return A stream containing the binary content. + */ + public InputStream getBinaryContent(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContentReference.java b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContentReference.java new file mode 100644 index 000000000..7c4e6d913 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSContentReference.java @@ -0,0 +1,17 @@ +package at.gv.egovernment.moa.spss.api.cmsverify; + +/** + * Encapsulates CMS content that is referenced by an URI. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CMSContentReference extends CMSContent { + /** + * Gets the reference URI from wher the content can be retrieved. + * + * @return The reference URI. + */ + public String getReference(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSDataObject.java b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSDataObject.java new file mode 100644 index 000000000..37f6fd396 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/CMSDataObject.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.cmsverify; + +import at.gv.egovernment.moa.spss.api.common.MetaInfo; + +/** + * A data object used for verification of CMS signatures. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CMSDataObject { + /** + * Gets the meta information of the content. + * + * @return An object containig the meta information. + */ + public MetaInfo getMetaInfo(); + /** + * Gets the actual content of the data object. + * + * @return The actual content. + */ + public CMSContent getContent(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureRequest.java b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureRequest.java new file mode 100644 index 000000000..6d1f389af --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureRequest.java @@ -0,0 +1,52 @@ +package at.gv.egovernment.moa.spss.api.cmsverify; + +import java.io.InputStream; +import java.util.Date; + +/** + * Object that encapsulates a request to verify a CMS signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyCMSSignatureRequest { + /** + * Indicates, that signature checks for all signatories must be returned. + */ + public static int[] ALL_SIGNATORIES = new int[] { -1 }; + /** + * Gets the positions of signatories whose signature must be verified. + * + * @return The positions of signatories. + */ + public int[] getSignatories(); + /** + * Gets the date and time for which the signature verification has to + * be performed. + * + * @return Date and time for which the signature verification has + * to be performed. + */ + public Date getDateTime(); + /** + * Gets the binary CMS signature. + * + * @return An <code>InputStream</code> from which the binary CMS signature + * can be read. + */ + public InputStream getCMSSignature(); + /** + * Gets the data object necessary for the verification. + * + * @return The data object necessary for verification. + */ + public CMSDataObject getDataObject(); + /** + * Gets the profile ID of trusted certificates to be used for signature + * verification. + * + * @return The profile ID of trusted certificates. + */ + public String getTrustProfileId(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureResponse.java b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureResponse.java new file mode 100644 index 000000000..5f2e6d255 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureResponse.java @@ -0,0 +1,21 @@ +package at.gv.egovernment.moa.spss.api.cmsverify; + +import java.util.List; + + +/** + * Object that encapsulates the response on a request to verify a CMS + * signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyCMSSignatureResponse { + /** + * Gets the response elements. + * + * @return The response elements. + */ + public List getResponseElements(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureResponseElement.java b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureResponseElement.java new file mode 100644 index 000000000..49ddb9419 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/cmsverify/VerifyCMSSignatureResponseElement.java @@ -0,0 +1,32 @@ +package at.gv.egovernment.moa.spss.api.cmsverify; + +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; + +/** + * Contains detailed information about the verification of a signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyCMSSignatureResponseElement { + /** + * Gets a SignerInfo element according to CMS. + * + * @return The SignerInfo element according to CMS. + */ + public SignerInfo getSignerInfo(); + /** + * Gets the result of the signature verification. + * + * @return The result of the signature verification. + */ + public CheckResult getSignatureCheck(); + /** + * Gets the result of the certificate verification. + * + * @return The result of the certificate verification. + */ + public CheckResult getCertificateCheck(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/Base64Transform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/Base64Transform.java new file mode 100644 index 000000000..94785727d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/Base64Transform.java @@ -0,0 +1,13 @@ +package at.gv.egovernment.moa.spss.api.common; + +/** + * A <code>Transform</code> performing a Base64 decoding. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface Base64Transform extends Transform { + /** Algorithm URI of the Base64 <code>Transform</code> type. */ + public static final String BASE64_DECODING = + "http://www.w3.org/2000/09/xmldsig#base64"; +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/CanonicalizationTransform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/CanonicalizationTransform.java new file mode 100644 index 000000000..352461e52 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/CanonicalizationTransform.java @@ -0,0 +1,17 @@ +package at.gv.egovernment.moa.spss.api.common; + +import at.gv.egovernment.moa.util.Constants; + +/** + * A canonicalization type of <code>Transform</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface CanonicalizationTransform extends Transform { + /** Algorithm URI of canonical XML. */ + public static final String CANONICAL_XML = Constants.C14N_URI; + /** Algorithm URI of canonical XML with comments. */ + public static final String CANONICAL_XML_WITH_COMMENTS = + Constants.C14N_WITH_COMMENTS_URI; +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/CheckResult.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/CheckResult.java new file mode 100644 index 000000000..974483d82 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/CheckResult.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.common; + +import org.w3c.dom.NodeList; + +/** + * Object encapsulating the result of a signature verification. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CheckResult { + /** + * Gets the result code. + * + * @return The result code. + */ + public int getCode(); + /** + * Gets descriptive information. + * + * @return Descriptive information. + */ + public NodeList getInfo(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/Content.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/Content.java new file mode 100644 index 000000000..173e9d395 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/Content.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.spss.api.common; + +/** + * Encapsulates content data. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface Content { + /** + * Indicates that this object contains a URI reference to some content. + */ + public static final int REFERENCE_CONTENT = 0; + /** + * Indicates that this object contains binary content. + */ + public static final int BINARY_CONTENT = 1; + /** + * Indicates that this object contains XML content. + */ + public static final int XML_CONTENT = 2; + + /** + * Gets the type of content contained in this object. + * + * @return The type of content, either <code>BINARY_CONTENT</code> or + * <code>XML_CONTENT</code> + */ + public int getContentType(); + /** + * Gets the reference to the content data (a URI). + * + * @return The reference to the content data. + */ + public String getReference(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentBinary.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentBinary.java new file mode 100644 index 000000000..664afa406 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentBinary.java @@ -0,0 +1,21 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.io.InputStream; + +/** + * Encapsulates binary content. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface ContentBinary extends Content { + /** + * Get the binary content. + * + * @return An <code>InputStream</code> from which the binary content can + * be read. + */ + public InputStream getBinaryContent(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentReference.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentReference.java new file mode 100644 index 000000000..c10f0c2f8 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentReference.java @@ -0,0 +1,11 @@ +package at.gv.egovernment.moa.spss.api.common; + +/** + * Content containing a reference to content data. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface ContentReference extends Content { + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentXML.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentXML.java new file mode 100644 index 000000000..ad5930452 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ContentXML.java @@ -0,0 +1,19 @@ +package at.gv.egovernment.moa.spss.api.common; + +import org.w3c.dom.NodeList; + +/** + * Encapsulates arbitrary XML content. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface ContentXML extends Content { + /** + * Gets the XML content stored in this object. + * + * @return The XML content. + */ + public NodeList getXMLContent(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/ElementSelector.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ElementSelector.java new file mode 100644 index 000000000..862cb84da --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ElementSelector.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.util.Map; + +/** + * A class containing data for selecting single elements using an XPath + * expression. + * + * Derived classes are used to point to the <code>CreateSignatureLocation</code> + * and the <code>VerifySignatureLocation</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface ElementSelector { + /** + * Gets the XPath expression pointing to a single element. + * + * @return The XPath expression to select the signature parent element. + */ + public String getXPathExpression(); + /** + * Gets the namespace prefix to URI mapping to use when evaluating the XPath. + * + * @return The namespace prefix to URI mapping. + */ + public Map getNamespaceDeclarations(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/EnvelopedSignatureTransform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/EnvelopedSignatureTransform.java new file mode 100644 index 000000000..f951e35c0 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/EnvelopedSignatureTransform.java @@ -0,0 +1,15 @@ +package at.gv.egovernment.moa.spss.api.common; + +/** + * An enveloped signature type of <code>Transform</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface EnvelopedSignatureTransform extends Transform { + /** + * Algorithm URI of the enveloped signature type of <code>Transform</code>. + */ + public static final String ENVELOPED_SIGNATURE = + "http://www.w3.org/2000/09/xmldsig#enveloped-signature"; +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/ExclusiveCanonicalizationTransform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ExclusiveCanonicalizationTransform.java new file mode 100644 index 000000000..369270259 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/ExclusiveCanonicalizationTransform.java @@ -0,0 +1,27 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.util.List; + +import at.gv.egovernment.moa.util.Constants; + +/** + * An exclusive canonicalization type of <code>Transform</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface ExclusiveCanonicalizationTransform extends Transform { + /** Algorithm URI of exclusive canonical XML. */ + public static final String EXCLUSIVE_CANONICAL_XML = Constants.EXC_C14N_URI; + /** Algorithm URI of exclusive canonical XML with comments. */ + public static final String EXCLUSIVE_CANONICAL_XML_WITH_COMMENTS = + Constants.EXC_C14N_WITH_COMMENTS_URI; + + /** + * Sets the namespace prefixes that are handled in the same manner as in + * canonical XML. + * + * @return The inclusive namespace prefixes. + */ + public List getInclusiveNamespacePrefixes(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/MetaInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/MetaInfo.java new file mode 100644 index 000000000..fea0a1b42 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/MetaInfo.java @@ -0,0 +1,31 @@ +package at.gv.egovernment.moa.spss.api.common; + +import org.w3c.dom.NodeList; + +/** + * Object encapsulating descriptive meta information. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface MetaInfo { + /** + * Gets the mime type of the associated object. + * + * @return The mimetype of the associated object. + */ + public String getMimeType(); + /** + * Gets the descriptive information (URI). + * + * @return URI referencing the descriptive information. + */ + public String getDescription(); + /** + * Gets the elemental informations. + * + * @return The elemental informations. + */ + public NodeList getAnyElements(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/SignerInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/SignerInfo.java new file mode 100644 index 000000000..c3b4aaadc --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/SignerInfo.java @@ -0,0 +1,43 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.security.cert.X509Certificate; + + +/** + * Contains information about the signer. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface SignerInfo { + /** + * Gets the signer certificate. + * + * @return The signer certificate. + */ + public X509Certificate getSignerCertificate(); + /** + * Checks, whether the certificate contained in this object is qualified. + * + * @return <code>true</code>, if the certificate is qualified, otherwise + * <code>false</code>. + */ + public boolean isQualifiedCertificate(); + /** + * Checks, whether the certificate contained in this object is a + * public authority certificate. + * + * @return <code>true</code>, if the certificate is a public authority + * certificate, otherwise <code>false</code>. + */ + public boolean isPublicAuthority(); + /** + * Gets the public authority ID, if the certificate contained in this + * object is from a public authority. + * + * @return The public authority ID. + */ + public String getPublicAuhtorityID(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/Transform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/Transform.java new file mode 100644 index 000000000..49a4e7c35 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/Transform.java @@ -0,0 +1,16 @@ +package at.gv.egovernment.moa.spss.api.common; + +/** + * Base class for XMLDsig <code>Transform</code> elements. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface Transform { + /** + * Gets the algorithm URI of this <code>Transform</code>. + * + * @return The algorithm URI of this <code>Transform</code>. + */ + public String getAlgorithmURI(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/X509IssuerSerial.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/X509IssuerSerial.java new file mode 100644 index 000000000..d2ea88968 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/X509IssuerSerial.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.math.BigInteger; + +/** + * Contains an X.509 issuer distinguished name/serial number pair. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface X509IssuerSerial { + /** + * Gets the issuer distinguished name. + * + * @return The issuer distinguished name. + */ + public String getX509IssuerName(); + /** + * Gets the issuer serial number. + * + * @return The issuer serial number. + */ + public BigInteger getX509SerialNumber(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/XMLDataObjectAssociation.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XMLDataObjectAssociation.java new file mode 100644 index 000000000..e1e034222 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XMLDataObjectAssociation.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.common; + + +/** + * Object encapsulating arbitrary content and optional descriptive meta + * information. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface XMLDataObjectAssociation { + /** + * Gets descriptive meta information. + * + * @return The descriptive meta information. + */ + public MetaInfo getMetaInfo(); + /** + * Gets the actual content. + * + * @return The content of this association. + */ + public Content getContent(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathFilter.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathFilter.java new file mode 100644 index 000000000..247776ce0 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathFilter.java @@ -0,0 +1,38 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.util.Map; + +/** + * An XPath expression set operation. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface XPathFilter { + /** Subtract this filter's node set from the resulting node set. */ + public static final String SUBTRACT_TYPE = "subtract"; + /** Intersect this filter's node set with the resulting node set. */ + public static final String INTERSECT_TYPE = "intersect"; + /** Compute the union of this filter's node set and the resulting node set. */ + public static final String UNION_TYPE = "union"; + + /** + * Gets the type of this <code>XPathFilter</code>. + * + * @return The type of this <code>XPathFilter</code>. + */ + public String getFilterType(); + /** + * Gets the XPath expression for selecting the nodes. + * + * @return The XPath expression for selecting the nodes. + */ + public String getXPathExpression(); + /** + * Gets The namespace prefix to URI mapping used during evaluation of the + * XPath expression. + * + * @return The namespace prefix to URI mapping. + */ + public Map getNamespaceDeclarations(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathFilter2Transform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathFilter2Transform.java new file mode 100644 index 000000000..335d37dbf --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathFilter2Transform.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.util.List; + +/** + * An XPath type of <code>Transform</code> containing multiple filters for + * performing set operations on XPath selections. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface XPathFilter2Transform extends Transform { + /** Algorithm URI for the XPath Filter2 <code>Transform</code>. */ + public static final String XPATH_FILTER2 = + "http://www.w3.org/2002/06/xmldsig-filter2"; + + /** + * Gets the <code>XPathFilter</code>s contained in this + * <code>XPathFilter2Transform</code>. + * + * @return The <code>XPathFilter</code>s. + */ + public List getFilters(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathTransform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathTransform.java new file mode 100644 index 000000000..f1cc1a2bc --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XPathTransform.java @@ -0,0 +1,30 @@ +package at.gv.egovernment.moa.spss.api.common; + +import java.util.Map; + +/** + * A <code>Transform</code> performing an XPath selection. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface XPathTransform extends Transform { + /** Algorithm URI of the XPath <code>Transform</code>. */ + public static final String XPATH = + "http://www.w3.org/TR/1999/REC-xpath-19991116"; + + /** + * Gets the XPath expression used for selection. + * + * @return The XPath expression used for selection. + */ + public String getXPathExpression(); + /** + * Gets The namespace prefix to URI mapping used during evaluation of the + * XPath expression. + * + * @return The namespace prefix to URI mapping. + */ + public Map getNamespaceDeclarations(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/common/XSLTTransform.java b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XSLTTransform.java new file mode 100644 index 000000000..7f44bb060 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/common/XSLTTransform.java @@ -0,0 +1,23 @@ +package at.gv.egovernment.moa.spss.api.common; + +import org.w3c.dom.Element; + +/** + * A <code>Transform</code> containing an XSLT stylesheet. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface XSLTTransform extends Transform { + /** Algorithm URI for the XSLT type of <code>Transform</code>. */ + public static final String XSLT = + "http://www.w3.org/TR/1999/REC-xslt-19991116"; + + /** + * Gets the XSLT stylesheet element used for the transformation. + * + * @return The XSLT stylesheet element used for the transformation. + */ + public Element getStylesheet(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/Base64TransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/Base64TransformImpl.java new file mode 100644 index 000000000..4af075da2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/Base64TransformImpl.java @@ -0,0 +1,22 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.Base64Transform; + +/** + * Default implementation of <code>Base64Transform</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class Base64TransformImpl + extends TransformImpl + implements Base64Transform { + + /** + * Create a new <code>Base64TransformImpl</code> object. + */ + public Base64TransformImpl() { + setAlgorithmURI(BASE64_DECODING); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSContentExplicitImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSContentExplicitImpl.java new file mode 100644 index 000000000..dd700cf21 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSContentExplicitImpl.java @@ -0,0 +1,40 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.io.InputStream; + +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContentExcplicit; + +/** + * Default implementation of <code>CMSContentExplicit</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CMSContentExplicitImpl implements CMSContentExcplicit { + + /** The binary content, as a stream. */ + private InputStream binaryContent; + + /** + * Sets the binary content as a stream. + * + * @param content The binary content as a stream. + */ + public void setBinaryContent(InputStream content) { + this.binaryContent = content; + } + + public InputStream getBinaryContent() { + return binaryContent; + } + + /** + * Gets the type of content. + * + * @return EXPLICIT_CONTENT + */ + public int getContentType() { + return EXPLICIT_CONTENT; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSContentReferenceImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSContentReferenceImpl.java new file mode 100644 index 000000000..f9c080a0d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSContentReferenceImpl.java @@ -0,0 +1,38 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContentReference; + +/** + * Default implementation of <code>CMSContentReference</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CMSContentReferenceImpl implements CMSContentReference { + + /** The reference pointing to the actual data. */ + private String reference; + + /** + * Sets the reference URI. + * + * @param referenceURI The URI pointing to the content data. + */ + public void setReference(String referenceURI) { + this.reference = referenceURI; + } + + public String getReference() { + return reference; + } + + /** + * Gets the content type. + * + * @return REFERENCE_CONTENT + */ + public int getContentType() { + return REFERENCE_CONTENT; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSDataObjectImpl.java new file mode 100644 index 000000000..6eec4e847 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CMSDataObjectImpl.java @@ -0,0 +1,46 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; + +/** + * Default implementation of <code>CMLSDataObject</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CMSDataObjectImpl implements CMSDataObject { + + /** The <code>MetaInfo</code> associated with the CMS data object. */ + private MetaInfo metaInfo; + /** The <code>CMSContent</code> contained in this data object. */ + private CMSContent cmsContent; + + /** + * Sets the meta information associated with the CMS data object. + * + * @param metaInfo The meta information. + */ + public void setMetaInfo(MetaInfo metaInfo) { + this.metaInfo = metaInfo; + } + + public MetaInfo getMetaInfo() { + return metaInfo; + } + + /** + * Sets the data of this <code>CMSDataObject</code>. + * + * @param cmsContent The actual data of this <code>CMSDataObject</code>. + */ + public void setContent(CMSContent cmsContent) { + this.cmsContent = cmsContent; + } + + public CMSContent getContent() { + return cmsContent; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CanonicalizationTransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CanonicalizationTransformImpl.java new file mode 100644 index 000000000..cf446d1b4 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CanonicalizationTransformImpl.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.CanonicalizationTransform; + +/** + * Default implementation of <code>CanonicalizationTransform</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CanonicalizationTransformImpl + extends TransformImpl + implements CanonicalizationTransform { + + /** + * Create a new <code>CanonicalizationTransformImpl</code> object. + * + * @param algorithmURI Algorithm URI of the canonicalization + * <code>Transform</code> type. + */ + public CanonicalizationTransformImpl(String algorithmURI) { + setAlgorithmURI(algorithmURI); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CheckResultImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CheckResultImpl.java new file mode 100644 index 000000000..2acb12e51 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CheckResultImpl.java @@ -0,0 +1,52 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.spss.api.common.CheckResult; + +/** + * Default implementation of <code>CheckResult</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CheckResultImpl implements CheckResult { + /** The result code. */ + private int code; + + /** Additional information. */ + private NodeList info; + + /** + * Sets a result code. + * + * @param code The result code. + */ + public void setCode(int code) { + this.code = code; + } + + /** + * @see at.gv.egovernment.moa.spss.api.CheckResult#getCode() + */ + public int getCode() { + return code; + } + + /** + * Sets a descriptive information. + * + * @param info The descriptive information. + */ + public void setInfo(NodeList info) { + this.info = info; + } + + /** + * @see at.gv.egovernment.moa.spss.api.CheckResult#getInfo() + */ + public NodeList getInfo() { + return info; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentBinaryImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentBinaryImpl.java new file mode 100644 index 000000000..bbed6bf8b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentBinaryImpl.java @@ -0,0 +1,40 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.io.InputStream; + +import at.gv.egovernment.moa.spss.api.common.ContentBinary; + +/** + * Default implementation of <code>ContentBinary</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class ContentBinaryImpl extends ContentImpl implements ContentBinary { + + /** The binary content as a stream. */ + private InputStream binaryContent; + + /** + * Sets the binary content as a stream. + * + * @param binaryContent The binary content as a stream. + */ + public void setBinaryContent(InputStream binaryContent) { + this.binaryContent = binaryContent; + } + + public InputStream getBinaryContent() { + return binaryContent; + } + + /** + * Gets the type of content. + * + * @return BINARY_CONTENT + */ + public int getContentType() { + return BINARY_CONTENT; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentImpl.java new file mode 100644 index 000000000..7f331d2cd --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentImpl.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.Content; + +/** + * Default base class for <code>Content</code> implementations. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class ContentImpl implements Content { + /** The reference pointing to the content data. */ + private String reference; + + /** + * Sets the reference pointing to the content data. + * + * @param referenceURI The URI of the content data. + */ + public void setReference(String referenceURI) { + this.reference = referenceURI; + } + + public String getReference() { + return reference; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentReferenceImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentReferenceImpl.java new file mode 100644 index 000000000..50609aa0e --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentReferenceImpl.java @@ -0,0 +1,24 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.ContentReference; + +/** + * Default implementation of <code>ContentReference</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ContentReferenceImpl + extends ContentImpl + implements ContentReference { + + /** + * Gets the type of content. + * + * @return REFERENCE_CONTENT + */ + public int getContentType() { + return REFERENCE_CONTENT; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentXMLImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentXMLImpl.java new file mode 100644 index 000000000..c03f5edde --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ContentXMLImpl.java @@ -0,0 +1,40 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.spss.api.common.ContentXML; + +/** + * Default implementation of <code>ContentXML</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class ContentXMLImpl extends ContentImpl implements ContentXML { + + /** The nodes making up the XML content. */ + private NodeList xmlContent; + + /** + * Sets the nodes making up the XML content. + * + * @param xmlContent The XML content. + */ + public void setXMLContent(NodeList xmlContent) { + this.xmlContent = xmlContent; + } + + public NodeList getXMLContent() { + return xmlContent; + } + + /** + * Gets the type of content. + * + * @return XML_CONTENT + */ + public int getContentType() { + return XML_CONTENT; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureEnvironmentProfileExplicitImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureEnvironmentProfileExplicitImpl.java new file mode 100644 index 000000000..22e4cd61d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureEnvironmentProfileExplicitImpl.java @@ -0,0 +1,66 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation; + +/** + * Default implementation of + * <codeCreateSignatureEnvironmentProfileExplicit</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class CreateSignatureEnvironmentProfileExplicitImpl + implements CreateSignatureEnvironmentProfileExplicit { + + /** The insertion location of the signature to be created. */ + private CreateSignatureLocation createSignatureLocation; + + /** Supplemental information for evaluating the signature environment. */ + private List supplements; + + /** + * Sets the insertion location of the signature to be created. + * + * @param createSignatureLocation The insertion location of the signature to + * be created. + */ + public void setCreateSignatureLocation(CreateSignatureLocation createSignatureLocation) { + this.createSignatureLocation = createSignatureLocation; + } + + public CreateSignatureLocation getCreateSignatureLocation() { + return createSignatureLocation; + } + + /** + * Sets the supplemental information for evaluating the signature + * environment. + * + * @param supplements The supplemental information. + */ + public void setSupplements(List supplements) { + this.supplements = + supplements != null + ? Collections.unmodifiableList(new ArrayList(supplements)) + : null; + } + + public List getSupplements() { + return supplements; + } + + /** + * Gets the type of profile. + * + * @return EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE + */ + public int getCreateSignatureEnvironmentProfileType() { + return EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureEnvironmentProfileIDImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureEnvironmentProfileIDImpl.java new file mode 100644 index 000000000..1c7dc6439 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureEnvironmentProfileIDImpl.java @@ -0,0 +1,39 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileID; + +/** + * Default implementation of <code>CreateSignatureEnvironmentProfileID</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class CreateSignatureEnvironmentProfileIDImpl + implements CreateSignatureEnvironmentProfileID { + + /** The profile ID. */ + private String createSignatureEnvironmentProfileID; + + /** + * Sets the profile ID. + * + * @param profileID The profile ID. + */ + public void setCreateSignatureEnvironmentProfileID(String profileID) { + this.createSignatureEnvironmentProfileID = profileID; + } + + public String getCreateSignatureEnvironmentProfileID() { + return createSignatureEnvironmentProfileID; + } + + /** + * Gets the type of profile. + * + * @return ID_CREATESIGNATUREENVIRONMENTPROFILE + */ + public int getCreateSignatureEnvironmentProfileType() { + return ID_CREATESIGNATUREENVIRONMENTPROFILE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureInfoImpl.java new file mode 100644 index 000000000..097af7fff --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureInfoImpl.java @@ -0,0 +1,50 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo; + +/** + * Default implementation of <code>CreateSignatureInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CreateSignatureInfoImpl implements CreateSignatureInfo { + + /** The signature environment that will contain the newly created + * signature. */ + private Content createSignatureEnvironment; + + /** Additional information about the signature environment. */ + private CreateSignatureEnvironmentProfile createSignatureEnvironmentProfile; + + /** + * Sets the signature environment that will contain the newly created + * signature. + * + * @param createSignatureEnvironment The signature environment. + */ + public void setCreateSignatureEnvironment(Content createSignatureEnvironment) { + this.createSignatureEnvironment = createSignatureEnvironment; + } + + public Content getCreateSignatureEnvironment() { + return createSignatureEnvironment; + } + + /** + * Sets the signature environment profile containing additional information + * about the signature environment. + * + * @param profile The signature environment profile. + */ + public void setCreateSignatureEnvironmentProfile(CreateSignatureEnvironmentProfile profile) { + this.createSignatureEnvironmentProfile = profile; + } + + public CreateSignatureEnvironmentProfile getCreateSignatureEnvironmentProfile() { + return createSignatureEnvironmentProfile; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureLocationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureLocationImpl.java new file mode 100644 index 000000000..c0b36f505 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateSignatureLocationImpl.java @@ -0,0 +1,31 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation; + +/** + * Default implementation of <code>CreateSignatureLocation</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CreateSignatureLocationImpl + extends ElementSelectorImpl + implements CreateSignatureLocation { + + /** The index of the newly created signature. */ + private int index; + + /** + * Sets the index of the newly created signature. + * + * @param index The index of the newly created signature. + */ + public void setIndex(int index) { + this.index = index; + } + + public int getIndex() { + return index; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoImpl.java new file mode 100644 index 000000000..ff4108248 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoImpl.java @@ -0,0 +1,51 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.common.MetaInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfo; + +/** + * Default implementation of <code>CreateTransformsInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CreateTransformsInfoImpl implements CreateTransformsInfo { + /** The dsig:Transforms. */ + private List transforms; + /** Meta information about the data resulting from the transforms. */ + private MetaInfo finalDataMetaInfo; + + /** + * Sets the transforms. + * + * @param transforms The transforms. + */ + public void setTransforms(List transforms) { + this.transforms = + transforms != null + ? Collections.unmodifiableList(new ArrayList(transforms)) + : null; + } + + public List getTransforms() { + return transforms; + } + + /** + * Sets the meta information about the data resulting from the transforms. + * + * @param finalDataMetaInfo The meta information. + */ + public void setFinalDataMetaInfo(MetaInfo finalDataMetaInfo) { + this.finalDataMetaInfo = finalDataMetaInfo; + } + + public MetaInfo getFinalDataMetaInfo() { + return finalDataMetaInfo; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoProfileExplicitImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoProfileExplicitImpl.java new file mode 100644 index 000000000..508b6c083 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoProfileExplicitImpl.java @@ -0,0 +1,62 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileExplicit; + +/** + * Default implementation of <code>CreateTransformsInfoProfileExplicit</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CreateTransformsInfoProfileExplicitImpl + implements CreateTransformsInfoProfileExplicit { + + /** Transformation information. */ + private CreateTransformsInfo transformsInfo; + /** Additional data for the transformations. */ + private List supplements = new ArrayList(); + + /** + * Sets the transformation information. + * + * @param transformsInfo The transformation information. + */ + public void setCreateTransformsInfo(CreateTransformsInfo transformsInfo) { + this.transformsInfo = transformsInfo; + } + + public CreateTransformsInfo getCreateTransformsInfo() { + return transformsInfo; + } + + /** + * Sets the additional data for the transformations. + * + * @param supplements The additional data. + */ + public void setSupplements(List supplements) { + this.supplements = + supplements != null + ? Collections.unmodifiableList(new ArrayList(supplements)) + : null; + } + + public List getSupplements() { + return supplements; + } + + /** + * Gets the type of profile. + * + * @return EXPLICIT_CREATETRANSFORMSINFOPROFILE + */ + public int getCreateTransformsInfoProfileType() { + return EXPLICIT_CREATETRANSFORMSINFOPROFILE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoProfileIDImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoProfileIDImpl.java new file mode 100644 index 000000000..5cd1fcc48 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateTransformsInfoProfileIDImpl.java @@ -0,0 +1,38 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileID; + +/** + * Default implementation of <code>CreateTransformsInfoProfileID</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CreateTransformsInfoProfileIDImpl + implements CreateTransformsInfoProfileID { + + /** The profile ID. */ + private String createTransformsID; + + /** + * Sets the profile ID. + * @param createTransformsID The profile ID. + */ + public void setCreateTransformsInfoProfileID(String createTransformsID) { + this.createTransformsID = createTransformsID; + } + + public String getCreateTransformsInfoProfileID() { + return createTransformsID; + } + + /** + * Gets the type of profile. + * + * @return ID_CREATETRANSFORMSINFOPROFILE + */ + public int getCreateTransformsInfoProfileType() { + return ID_CREATETRANSFORMSINFOPROFILE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateXMLSignatureRequestImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateXMLSignatureRequestImpl.java new file mode 100644 index 000000000..08f94cc31 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateXMLSignatureRequestImpl.java @@ -0,0 +1,53 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; + +/** + * Default implementation of <code>CreateXMLSignatureRequest</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CreateXMLSignatureRequestImpl + implements CreateXMLSignatureRequest { + + /** The identifier for selecting the private keys for creating the signature.*/ + private String keyIdentifier; + /** Information for creating a single signature. */ + private List singleSignatureInfos = new ArrayList(); + + /** + * Sets the identifier for selecting the private keys for creating the + * signature. + * + * @param keyIdentifier The identifier for selecting the private keys. + */ + public void setKeyIdentifier(String keyIdentifier) { + this.keyIdentifier = keyIdentifier; + } + + public String getKeyIdentifier() { + return keyIdentifier; + } + + /** + * Sets the information for creating single signatures. + * + * @param singleSignaureInfos The information for creating single signatures. + */ + public void setSingleSignatureInfos(List singleSignaureInfos) { + this.singleSignatureInfos = + singleSignaureInfos != null + ? Collections.unmodifiableList(new ArrayList(singleSignaureInfos)) + : null; + } + + public List getSingleSignatureInfos() { + return singleSignatureInfos; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateXMLSignatureResponseImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateXMLSignatureResponseImpl.java new file mode 100644 index 000000000..590258e30 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/CreateXMLSignatureResponseImpl.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; + +/** + * Default implementation of <code>CreateXMLSignatureResponse</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class CreateXMLSignatureResponseImpl + implements CreateXMLSignatureResponse { + + /** The elements contained in the response. */ + private List responseElements = new ArrayList(); + + /** + * Sets the elements contained in the response. + * + * @param responseElements The response elements. + */ + public void setResponseElements(List responseElements) { + this.responseElements = + responseElements != null + ? Collections.unmodifiableList(new ArrayList(responseElements)) + : null; + } + + public List getResponseElements() { + return responseElements; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/DataObjectInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/DataObjectInfoImpl.java new file mode 100644 index 000000000..8ab2241de --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/DataObjectInfoImpl.java @@ -0,0 +1,79 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo; + +/** + * Default implementation of <code>DataObjectInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class DataObjectInfoImpl implements DataObjectInfo { + /** The signature structure type. */ + private String stucture; + /** Whether a reference will be placed in the signature itself or in the + * manifest */ + private boolean childOfManifest; + /** The data object to be signed. */ + private Content dataObject; + /** The profile containing additional information for the transformations. */ + private CreateTransformsInfoProfile createTransformsInfoProfile; + + /** + * Sets the signature structure type. + * + * @param structure The signature structure type. + */ + public void setStructure(String structure) { + this.stucture = structure; + } + + public String getStructure() { + return stucture; + } + + /** + * Sets whether a reference will be placed in the signature itself or in the + * manifest. + * + * @param childOfManifest Whether to put the reference in the signature of + * in the manifest. + */ + public void setChildOfManifest(boolean childOfManifest) { + this.childOfManifest = childOfManifest; + } + + public boolean isChildOfManifest() { + return childOfManifest; + } + + /** + * Sets the data object to be signed. + * + * @param dataObject The data object to be signed. + */ + public void setDataObject(Content dataObject) { + this.dataObject = dataObject; + } + + public Content getDataObject() { + return dataObject; + } + + /** + * Sets additional information for the transformations. + * + * @param profile The profile containing additional information for the + * transformations. + */ + public void setCreateTransformsInfoProfile(CreateTransformsInfoProfile profile) { + this.createTransformsInfoProfile = profile; + } + + public CreateTransformsInfoProfile getCreateTransformsInfoProfile() { + return createTransformsInfoProfile; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ElementSelectorImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ElementSelectorImpl.java new file mode 100644 index 000000000..e460bd584 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ElementSelectorImpl.java @@ -0,0 +1,47 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.HashMap; +import java.util.Map; + +import at.gv.egovernment.moa.spss.api.common.ElementSelector; + +/** + * Default implementation of <code>ElementSelector</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class ElementSelectorImpl implements ElementSelector { + /** The XPath expression pointing to the element. */ + private String xPathExpression; + /** The namespace declarations to apply for evaluating the XPath */ + private Map namespaceDeclarations = new HashMap(); + + /** + * Sets the XPath expression pointing to the element. + * + * @param xPathExpression XPath expression pointing to the element. + */ + public void setXPathExpression(String xPathExpression) { + this.xPathExpression = xPathExpression; + } + + public String getXPathExpression() { + return xPathExpression; + } + + /** + * Sets namespace declarations to apply for evaluating the XPath. + * + * @param namespaceDeclarations The namespace declarations to apply for + * evaluating the XPath. + */ + public void setNamespaceDeclarations(Map namespaceDeclarations) { + this.namespaceDeclarations = namespaceDeclarations; + } + + public Map getNamespaceDeclarations() { + return namespaceDeclarations; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/EnvelopedSignatureTransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/EnvelopedSignatureTransformImpl.java new file mode 100644 index 000000000..a1be3d86a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/EnvelopedSignatureTransformImpl.java @@ -0,0 +1,22 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.EnvelopedSignatureTransform; + +/** + * Default implementation of <code>EnvelopedSignatureTransform</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class EnvelopedSignatureTransformImpl + extends TransformImpl + implements EnvelopedSignatureTransform { + + /** + * Create a <code>EnvelopedSignatureTransformImpl</code>. + */ + public EnvelopedSignatureTransformImpl() { + setAlgorithmURI(ENVELOPED_SIGNATURE); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ErrorResponseImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ErrorResponseImpl.java new file mode 100644 index 000000000..d7047ab44 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ErrorResponseImpl.java @@ -0,0 +1,52 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse; + +/** + * Default implementation of <code>ErrorResponse</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class ErrorResponseImpl implements ErrorResponse { + /** The error code. */ + private int code; + /** Verbose error message. */ + private String info; + + /** + * Sets the error code. + * + * @param code The error code. + */ + public void setErrorCode(int code) { + this.code = code; + } + + public int getErrorCode() { + return code; + } + + /** + * Sets the verbose error information. + * + * @param info The verbose error information. + */ + public void setInfo(String info) { + this.info = info; + } + + public String getInfo() { + return info; + } + + /** + * Gets the response type. + * + * @return ERROR_RESPONSE + */ + public int getResponseType() { + return ERROR_RESPONSE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ExclusiveCanonicalizationTransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ExclusiveCanonicalizationTransformImpl.java new file mode 100644 index 000000000..bf21c8634 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ExclusiveCanonicalizationTransformImpl.java @@ -0,0 +1,48 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.common.ExclusiveCanonicalizationTransform; + +/** + * Default implementation of <code>ExclusiveCanonicalizationTransform</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ExclusiveCanonicalizationTransformImpl + extends TransformImpl + implements ExclusiveCanonicalizationTransform { + + /** The namespaces to treat according to canonical XML. */ + private List inclusiveNamespacePrefixes; + + /** + * Create a <code>ExclusiveCanonicalizationTransformImpl</code> object. + * + * @param algorithmURI The algorithm URI identifying the transformation + * algorithm. + */ + public ExclusiveCanonicalizationTransformImpl(String algorithmURI) { + setAlgorithmURI(algorithmURI); + } + + /** + * Sets the namespaces to treat according to canonical XML. + * @param inclusiveNamespacePrefixes The namespaces to treat according to + * canonical XML. + */ + public void setInclusiveNamespacePrefixes(List inclusiveNamespacePrefixes) { + this.inclusiveNamespacePrefixes = + inclusiveNamespacePrefixes != null + ? Collections.unmodifiableList(new ArrayList(inclusiveNamespacePrefixes)) + : null; + } + + public List getInclusiveNamespacePrefixes() { + return inclusiveNamespacePrefixes; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ManifestRefsCheckResultImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ManifestRefsCheckResultImpl.java new file mode 100644 index 000000000..9174e3a46 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ManifestRefsCheckResultImpl.java @@ -0,0 +1,44 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResultInfo; + +/** + * Default implementation of <code>ManifestRefsCheckResult</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class ManifestRefsCheckResultImpl implements ManifestRefsCheckResult { + /** The numerical check code. */ + private int code; + /** Additional information about the check. */ + private ManifestRefsCheckResultInfo info; + + /** + * Sets the check code. + * + * @param code A numerical representation of the result of the manifest check. + */ + public void setCode(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + /** + * Sets a reference to the manifest. + * + * @param info The reference to the manifest. + */ + public void setInfo(ManifestRefsCheckResultInfo info) { + this.info = info; + } + + public ManifestRefsCheckResultInfo getInfo() { + return info; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ManifestRefsCheckResultInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ManifestRefsCheckResultInfoImpl.java new file mode 100644 index 000000000..0071a14f3 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ManifestRefsCheckResultInfoImpl.java @@ -0,0 +1,32 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResultInfo; + +/** + * Default implementation of <code>ManifestRefsCheckResultInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class ManifestRefsCheckResultInfoImpl + extends ReferencesCheckResultInfoImpl + implements ManifestRefsCheckResultInfo { + + /** The position of the signature reference containing the reference to the + * manifest being described by this object.*/ + private int referringSignatureReference; + + /** + * Sets the position of the signature reference containing the reference to + * the manifest being described by this object. + * @param referringSignatureReference The position of the signature reference. + */ + public void setReferringSignatureReference(int referringSignatureReference) { + this.referringSignatureReference = referringSignatureReference; + } + + public int getReferringSignatureReference() { + return referringSignatureReference; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/MetaInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/MetaInfoImpl.java new file mode 100644 index 000000000..c435dd8fd --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/MetaInfoImpl.java @@ -0,0 +1,59 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.spss.api.common.MetaInfo; + +/** + * Default implementation of <code>MetaInfo</code>. + * @author Fatemeh Philippi + * @version $Id$ + */ +public class MetaInfoImpl implements MetaInfo { + /** Information about the MIME type. */ + private String mimeType; + /** URI pointing to a description of the content. */ + private String description; + /** Descriptive XML content. */ + private NodeList anyElements; + + /** + * Sets the MIME type. + * + * @param mimeType The MIME type to set. + */ + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + public String getMimeType() { + return mimeType; + } + + /** + * Sets the URI pointing to a description of the content. + * + * @param description The URI pointing to a description of the content. + */ + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + + /** + * Sets descriptive XML content. + * + * @param anyElements The elements to set. + */ + public void setAnyElements(NodeList anyElements) { + this.anyElements = anyElements; + } + + public NodeList getAnyElements() { + return anyElements; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferenceInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferenceInfoImpl.java new file mode 100644 index 000000000..923a4bce1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferenceInfoImpl.java @@ -0,0 +1,38 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; + +/** + * Default implementation of <code>ReferenceInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class ReferenceInfoImpl implements ReferenceInfo { + /** Profile containing the transforms allowed in the signature. */ + private List verifyTransformsInfoProfiles; + + /** + * Sets the transforms profile used for verifying the transforms contained + * in the signature. + * + * @param verifyTransformsInfoProfiles The profiles containing the transforms + * allowed in the signature. + */ + public void setVerifyTransformsInfoProfiles(List verifyTransformsInfoProfiles) { + this.verifyTransformsInfoProfiles = + verifyTransformsInfoProfiles != null + ? Collections.unmodifiableList( + new ArrayList(verifyTransformsInfoProfiles)) + : null; + } + + public List getVerifyTransformsInfoProfiles() { + return verifyTransformsInfoProfiles; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferencesCheckResultImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferencesCheckResultImpl.java new file mode 100644 index 000000000..6bb4d30ac --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferencesCheckResultImpl.java @@ -0,0 +1,46 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo; + +/** + * Default implementation of <code>ReferencesCheckResult</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ReferencesCheckResultImpl implements ReferencesCheckResult { + /** The check code. */ + private int code; + /** Additional information about the reference check. */ + private ReferencesCheckResultInfo info; + + /** + * Sets the check code. + * + * @param code A numerical representation of the result of the reference + * check. + */ + public void setCode(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + /** + * Sets additional information about the reference check. + * + * @param manifestRefsCheckResultInfo Additional information about the + * reference check. + */ + public void setInfo(ReferencesCheckResultInfo manifestRefsCheckResultInfo) { + this.info = manifestRefsCheckResultInfo; + } + + public ReferencesCheckResultInfo getInfo() { + return info; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferencesCheckResultInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferencesCheckResultInfoImpl.java new file mode 100644 index 000000000..a21b417ae --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/ReferencesCheckResultInfoImpl.java @@ -0,0 +1,46 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo; + +/** + * Default implementation of <code>ReferencesCheckResultInfo</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ReferencesCheckResultInfoImpl + implements ReferencesCheckResultInfo { + + /** Additional information about the references check. */ + private NodeList anyOtherInfo; + /** The indexes of the failed references. */ + private int[] failedReferences = new int[0]; + + /** + * Sets additional information about the references check. + * @param anyOtherInfo Additional information about the references check. + */ + public void setAnyOtherInfo(NodeList anyOtherInfo) { + this.anyOtherInfo = anyOtherInfo; + } + + public NodeList getAnyOtherInfo() { + return anyOtherInfo; + } + + /** + * Sets the indexes of the failed references. + * + * @param failedReferences The indexes of the failed references. + */ + public void setFailedReferences(int[] failedReferences) { + this.failedReferences = failedReferences; + } + + public int[] getFailedReferences() { + return failedReferences; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SPSSFactoryImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SPSSFactoryImpl.java new file mode 100644 index 000000000..ab6240f79 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SPSSFactoryImpl.java @@ -0,0 +1,559 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.io.InputStream; +import java.math.BigInteger; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; +import at.gv.egovernment.moa.spss.api.common.Transform; +import at.gv.egovernment.moa.spss.api.common.X509IssuerSerial; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; +import at.gv.egovernment.moa.spss.api.common.XPathFilter; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.SignatureEnvironmentResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResultInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; + +/** + * Default implementation of <code>SPSSFactory</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SPSSFactoryImpl extends SPSSFactory { + + public CreateXMLSignatureRequest createCreateXMLSignatureRequest( + String keyIdentifier, + List singleSignatureInfos) { + CreateXMLSignatureRequestImpl createXMLSignatureRequest = + new CreateXMLSignatureRequestImpl(); + createXMLSignatureRequest.setKeyIdentifier(keyIdentifier); + createXMLSignatureRequest.setSingleSignatureInfos(singleSignatureInfos); + return createXMLSignatureRequest; + } + + public SingleSignatureInfo createSingleSignatureInfo( + List dataObjectInfos, + CreateSignatureInfo createSignatureInfo, + boolean securityLayerConform) { + SingleSignatureInfoImpl singleSignatureInfo = new SingleSignatureInfoImpl(); + singleSignatureInfo.setDataObjectInfos(dataObjectInfos); + singleSignatureInfo.setCreateSignatureInfo(createSignatureInfo); + singleSignatureInfo.setSecurityLayerConform(securityLayerConform); + return singleSignatureInfo; + } + public DataObjectInfo createDataObjectInfo( + String structure, + boolean childOfManifest, + Content dataObject, + CreateTransformsInfoProfile createTransformsInfoProfile) { + DataObjectInfoImpl dataObjectInfo = new DataObjectInfoImpl(); + dataObjectInfo.setStructure(structure); + dataObjectInfo.setChildOfManifest(childOfManifest); + dataObjectInfo.setDataObject(dataObject); + dataObjectInfo.setCreateTransformsInfoProfile(createTransformsInfoProfile); + return dataObjectInfo; + } + + public CreateTransformsInfoProfile createCreateTransformsInfoProfile(String profileID) { + + CreateTransformsInfoProfileIDImpl createTransformsInfoProfile = + new CreateTransformsInfoProfileIDImpl(); + createTransformsInfoProfile.setCreateTransformsInfoProfileID(profileID); + return createTransformsInfoProfile; + } + + public CreateTransformsInfoProfile createCreateTransformsInfoProfile( + CreateTransformsInfo transformsInfo, + List supplements) { + CreateTransformsInfoProfileExplicitImpl createTransformsInfoProfile = + new CreateTransformsInfoProfileExplicitImpl(); + createTransformsInfoProfile.setCreateTransformsInfo(transformsInfo); + createTransformsInfoProfile.setSupplements(supplements); + return createTransformsInfoProfile; + } + + public CreateTransformsInfo createCreateTransformsInfo( + List transforms, + MetaInfo finalDataMetaInfo) { + CreateTransformsInfoImpl createTransformsInfo = + new CreateTransformsInfoImpl(); + + createTransformsInfo.setTransforms(transforms); + createTransformsInfo.setFinalDataMetaInfo(finalDataMetaInfo); + return createTransformsInfo; + } + + public CreateSignatureInfo createCreateSignatureInfo( + Content createSignatureEnvironment, + CreateSignatureEnvironmentProfile createSignatureEnvironmentProfile) { + CreateSignatureInfoImpl createSignatureInfo = new CreateSignatureInfoImpl(); + createSignatureInfo.setCreateSignatureEnvironment( + createSignatureEnvironment); + createSignatureInfo.setCreateSignatureEnvironmentProfile( + createSignatureEnvironmentProfile); + return createSignatureInfo; + } + + public CreateSignatureEnvironmentProfile createCreateSignatureEnvironmentProfile( + CreateSignatureLocation createSignatureLocation, + List supplements) { + CreateSignatureEnvironmentProfileExplicitImpl createSignatureEnvironmentProfile = + new CreateSignatureEnvironmentProfileExplicitImpl(); + createSignatureEnvironmentProfile.setCreateSignatureLocation( + createSignatureLocation); + createSignatureEnvironmentProfile.setSupplements(supplements); + return createSignatureEnvironmentProfile; + } + + public CreateSignatureLocation createCreateSignatureLocation( + String signatureLocationXPath, + int signatureLocationIndex, + Map namespaceDeclarations) { + CreateSignatureLocationImpl createSignatureLocation = + new CreateSignatureLocationImpl(); + createSignatureLocation.setIndex(signatureLocationIndex); + createSignatureLocation.setNamespaceDeclarations(namespaceDeclarations); + createSignatureLocation.setXPathExpression(signatureLocationXPath); + return createSignatureLocation; + } + + public CreateSignatureEnvironmentProfile createCreateSignatureEnvironmentProfile(String profileID) { + CreateSignatureEnvironmentProfileIDImpl createSignatureEnvironmentProfile = + new CreateSignatureEnvironmentProfileIDImpl(); + createSignatureEnvironmentProfile.setCreateSignatureEnvironmentProfileID( + profileID); + return createSignatureEnvironmentProfile; + } + + public CreateXMLSignatureResponse createCreateXMLSignatureResponse(List responseElements) { + CreateXMLSignatureResponseImpl createXMLSignatureResponse = + new CreateXMLSignatureResponseImpl(); + createXMLSignatureResponse.setResponseElements(responseElements); + return createXMLSignatureResponse; + } + + public SignatureEnvironmentResponse createSignatureEnvironmentResponse(Element signatureEnvironment) { + SignatureEnvironmentResponseImpl signatureEnvironmentResponse = + new SignatureEnvironmentResponseImpl(); + signatureEnvironmentResponse.setSignatureEnvironment(signatureEnvironment); + return signatureEnvironmentResponse; + } + + public ErrorResponse createErrorResponse(int code, String info) { + ErrorResponseImpl errorResponse = new ErrorResponseImpl(); + errorResponse.setErrorCode(code); + errorResponse.setInfo(info); + return errorResponse; + } + + public VerifyCMSSignatureRequest createVerifyCMSSignatureRequest( + int[] signatories, + Date dateTime, + InputStream cmsSignature, + CMSDataObject dataObject, + String trustProfileID) { + VerifyCMSSignatureRequestImpl verifyCMSSignatureRequest = + new VerifyCMSSignatureRequestImpl(); + verifyCMSSignatureRequest.setDateTime(dateTime); + verifyCMSSignatureRequest.setCMSSignature(cmsSignature); + verifyCMSSignatureRequest.setDataObject(dataObject); + verifyCMSSignatureRequest.setTrustProfileId(trustProfileID); + verifyCMSSignatureRequest.setSignatories(signatories); + return verifyCMSSignatureRequest; + } + + public CMSDataObject createCMSDataObject( + MetaInfo metaInfo, + CMSContent content) { + + CMSDataObjectImpl cmsDataObject = new CMSDataObjectImpl(); + cmsDataObject.setMetaInfo(metaInfo); + cmsDataObject.setContent(content); + + return cmsDataObject; + } + + public CMSContent createCMSContent(InputStream binaryContent) { + CMSContentExplicitImpl cmsContent = new CMSContentExplicitImpl(); + + cmsContent.setBinaryContent(binaryContent); + return cmsContent; + } + + public CMSContent createCMSContent(String referenceURI) { + CMSContentReferenceImpl cmsContent = new CMSContentReferenceImpl(); + + cmsContent.setReference(referenceURI); + return cmsContent; + } + + + public CMSDataObject createCMSDataObject( + MetaInfo metaInfo, + String referenceURI) { + CMSDataObjectImpl cmsDataObject = new CMSDataObjectImpl(); + CMSContentReferenceImpl cmsContent = new CMSContentReferenceImpl(); + cmsDataObject.setMetaInfo(metaInfo); + cmsContent.setReference(referenceURI); + return cmsDataObject; + } + + public VerifyCMSSignatureResponse createVerifyCMSSignatureResponse(List responseElements) { + VerifyCMSSinatureResponseImpl verifyCMSSignatureResponse = + new VerifyCMSSinatureResponseImpl(); + verifyCMSSignatureResponse.setResponseElements(responseElements); + return verifyCMSSignatureResponse; + } + + public VerifyCMSSignatureResponseElement createVerifyCMSSignatureResponseElement( + SignerInfo signerInfo, + CheckResult signatureCheck, + CheckResult certificateCheck) { + VerifyCMSSignatureResponseElementImpl verifyCMSSignatureResponseElement = + new VerifyCMSSignatureResponseElementImpl(); + verifyCMSSignatureResponseElement.setSignerInfo(signerInfo); + verifyCMSSignatureResponseElement.setSignatureCheck(signatureCheck); + verifyCMSSignatureResponseElement.setCertificateCheck(certificateCheck); + return verifyCMSSignatureResponseElement; + } + + public VerifyXMLSignatureRequest createVerifyXMLSignatureRequest( + Date dateTime, + VerifySignatureInfo verifySignatureInfo, + List supplementProfiles, + SignatureManifestCheckParams signatureManifestParams, + boolean returnHashInputData, + String trustProfileID) { + VerifyXMLSignatureRequestImpl verifyXMLSignatureRequest = + new VerifyXMLSignatureRequestImpl(); + verifyXMLSignatureRequest.setDateTime(dateTime); + verifyXMLSignatureRequest.setSignatureInfo(verifySignatureInfo); + verifyXMLSignatureRequest.setSupplementProfiles(supplementProfiles); + verifyXMLSignatureRequest.setSignatureManifestCheckParams( + signatureManifestParams); + verifyXMLSignatureRequest.setReturnHashInputData(returnHashInputData); + verifyXMLSignatureRequest.setTrustProfileId(trustProfileID); + return verifyXMLSignatureRequest; + } + + public VerifySignatureInfo createVerifySignatureInfo( + Content verifySignatureEnvironment, + VerifySignatureLocation verifySignatureLocation) { + VerifySignatureInfoImpl verifySignatureInfo = new VerifySignatureInfoImpl(); + verifySignatureInfo.setVerifySignatureEnvironment( + verifySignatureEnvironment); + verifySignatureInfo.setVerifySignatureLocation(verifySignatureLocation); + return verifySignatureInfo; + } + + public VerifySignatureLocation createVerifySignatureLocation( + String xPathExpression, + Map namespaceDeclarations) { + VerifySignatureLocationImpl verifySignatureLocation = + new VerifySignatureLocationImpl(); + verifySignatureLocation.setXPathExpression(xPathExpression); + verifySignatureLocation.setNamespaceDeclarations(namespaceDeclarations); + return verifySignatureLocation; + } + + public SupplementProfile createSupplementProfile(String profileID) { + SupplementProfileIDImpl supplementProfileID = new SupplementProfileIDImpl(); + supplementProfileID.setSupplementProfileID(profileID); + return supplementProfileID; + } + + public SupplementProfile createSupplementProfile(XMLDataObjectAssociation supplementProfile) { + SupplementProfileExplicitImpl supplementProfileExplicit = + new SupplementProfileExplicitImpl(); + supplementProfileExplicit.setSupplementProfile(supplementProfile); + return supplementProfileExplicit; + } + + public SignatureManifestCheckParams createSignatureManifestCheckParams( + List referenceInfos, + boolean returnReferenceInputData) { + SignatureManifestCheckParamsImpl signatureManifestCheckParams = + new SignatureManifestCheckParamsImpl(); + signatureManifestCheckParams.setReferenceInfos(referenceInfos); + signatureManifestCheckParams.setReturnReferenceInputData( + returnReferenceInputData); + return signatureManifestCheckParams; + } + + public ReferenceInfo createReferenceInfo(List verifyTransformsInfoProfiles) { + ReferenceInfoImpl referenceInfo = new ReferenceInfoImpl(); + referenceInfo.setVerifyTransformsInfoProfiles(verifyTransformsInfoProfiles); + return referenceInfo; + } + + public VerifyTransformsInfoProfile createVerifyTransformsInfoProfile( + List transforms, + List transformParameters) { + VerifyTransformsInfoProfileExplicitImpl verifyTransformsInfoProfile = + new VerifyTransformsInfoProfileExplicitImpl(); + + verifyTransformsInfoProfile.setTransforms(transforms); + verifyTransformsInfoProfile.setTransformParameters(transformParameters); + + return verifyTransformsInfoProfile; + } + + public VerifyTransformsInfoProfile createVerifyTransformsInfoProfile(String profileID) { + VerifyTransformsInfoProfileIDImpl verifyTransformsInfoProfile = + new VerifyTransformsInfoProfileIDImpl(); + verifyTransformsInfoProfile.setVerifyTransformsInfoProfileID(profileID); + return verifyTransformsInfoProfile; + } + + + public TransformParameter createTransformParameter(String URI, String digestMethod, byte[] digestValue) { + TransformPatameterHashImpl transformParameter = + new TransformPatameterHashImpl(); + transformParameter.setURI(URI); + transformParameter.setDigestMethod(digestMethod); + transformParameter.setDigestValue(digestValue); + return transformParameter; + } + + public TransformParameter createTransformParameter( + String URI, + InputStream binaryData) { + TransformParameterBinaryImpl transformParameter = + new TransformParameterBinaryImpl(); + transformParameter.setURI(URI); + transformParameter.setBinaryContent(binaryData); + return transformParameter; + } + + public TransformParameter createTransformParameter(String URI) { + TransformParameterURIImpl transformParameter = + new TransformParameterURIImpl(); + transformParameter.setURI(URI); + return transformParameter; + } + + public VerifyXMLSignatureResponse createVerifyXMLSignatureResponse( + SignerInfo signerInfo, + List hashInputDatas, + List referenceInputDatas, + ReferencesCheckResult signatureCheck, + ReferencesCheckResult signatureManifestCheck, + List xmlDsigManifestChecks, + CheckResult certificateCheck) { + VerifyXMLSignatureResponseImpl verifyXMLSignatureResponse = + new VerifyXMLSignatureResponseImpl(); + verifyXMLSignatureResponse.setSignerInfo(signerInfo); + verifyXMLSignatureResponse.setHashInputDatas(hashInputDatas); + verifyXMLSignatureResponse.setReferenceInputDatas(referenceInputDatas); + verifyXMLSignatureResponse.setSignatureCheck(signatureCheck); + verifyXMLSignatureResponse.setSignatureManifestCheck( + signatureManifestCheck); + verifyXMLSignatureResponse.setXMLDsigManifestChecks(xmlDsigManifestChecks); + verifyXMLSignatureResponse.setCertificateCheck(certificateCheck); + return verifyXMLSignatureResponse; + } + + public ReferencesCheckResult createReferencesCheckResult( + int code, + ReferencesCheckResultInfo info) { + ReferencesCheckResultImpl referencesCheckResult = + new ReferencesCheckResultImpl(); + referencesCheckResult.setCode(code); + referencesCheckResult.setInfo(info); + return referencesCheckResult; + } + + public ReferencesCheckResultInfo createReferencesCheckResultInfo( + NodeList anyOtherInfo, + int[] failedReferences) { + ReferencesCheckResultInfoImpl referencesCheckResultInfo = + new ReferencesCheckResultInfoImpl(); + referencesCheckResultInfo.setAnyOtherInfo(anyOtherInfo); + referencesCheckResultInfo.setFailedReferences(failedReferences); + return referencesCheckResultInfo; + } + + public ManifestRefsCheckResult createManifestRefsCheckResult( + int code, + ManifestRefsCheckResultInfo info) { + ManifestRefsCheckResultImpl manifestRefsCheckResult = + new ManifestRefsCheckResultImpl(); + manifestRefsCheckResult.setCode(code); + manifestRefsCheckResult.setInfo(info); + return manifestRefsCheckResult; + } + + public ManifestRefsCheckResultInfo createManifestRefsCheckResultInfo( + NodeList anyOtherInfo, + int[] failedReferences, + int referringSigReference) { + ManifestRefsCheckResultInfoImpl manifestRefsCheckResultInfo = + new ManifestRefsCheckResultInfoImpl(); + manifestRefsCheckResultInfo.setAnyOtherInfo(anyOtherInfo); + manifestRefsCheckResultInfo.setReferringSignatureReference( + referringSigReference); + manifestRefsCheckResultInfo.setFailedReferences(failedReferences); + return manifestRefsCheckResultInfo; + } + + public Content createContent(InputStream binaryData, String referenceURI) { + ContentBinaryImpl content = new ContentBinaryImpl(); + content.setBinaryContent(binaryData); + content.setReference(referenceURI); + return content; + } + + public Content createContent(String referenceURI) { + ContentReferenceImpl content = new ContentReferenceImpl(); + content.setReference(referenceURI); + return content; + } + + public Content createContent(NodeList xmlData, String referenceURI) { + ContentXMLImpl content = new ContentXMLImpl(); + content.setXMLContent(xmlData); + content.setReference(referenceURI); + return content; + } + + public XMLDataObjectAssociation createXMLDataObjectAssociation( + MetaInfo metaInfo, + Content xmlContent) { + XMLDataObjectAssociationImpl xmlDataObjectAssociation = + new XMLDataObjectAssociationImpl(); + xmlDataObjectAssociation.setMetaInfo(metaInfo); + xmlDataObjectAssociation.setContent(xmlContent); + return xmlDataObjectAssociation; + } + + public MetaInfo createMetaInfo( + String mimeType, + String description, + NodeList otherInfo) { + MetaInfoImpl metaInfo = new MetaInfoImpl(); + metaInfo.setMimeType(mimeType); + metaInfo.setDescription(description); + metaInfo.setAnyElements(otherInfo); + return metaInfo; + } + + public Transform createCanonicalizationTransform(String algorithmURI) { + CanonicalizationTransformImpl transform = new CanonicalizationTransformImpl(algorithmURI); + return transform; + } + + public Transform createExclusiveCanonicalizationTransform(String algorithmURI, List inclusiveNamespacePrefixes) { + ExclusiveCanonicalizationTransformImpl transform = new ExclusiveCanonicalizationTransformImpl(algorithmURI); + transform.setInclusiveNamespacePrefixes(inclusiveNamespacePrefixes); + return transform; + } + + public Transform createBase64Transform() { + Base64TransformImpl transform = new Base64TransformImpl(); + return transform; + } + + public Transform createEnvelopedSignatureTransform() { + EnvelopedSignatureTransformImpl transform = + new EnvelopedSignatureTransformImpl(); + return transform; + } + + public Transform createXSLTTransform(Element styleSheet) { + XSLTransformImpl transform = new XSLTransformImpl(); + transform.setStylesheet(styleSheet); + return transform; + } + + public Transform createXPathTransform( + String xPathExpression, + Map namespaceDeclarations) { + XPathTransformImpl transform = new XPathTransformImpl(); + transform.setXPathExpression(xPathExpression); + transform.setNamespaceDelcarations(namespaceDeclarations); + return transform; + } + + public Transform createXPathFilter2Transform(List xPathFilters) { + XPathFilter2TransformImpl transform = new XPathFilter2TransformImpl(); + transform.setFilters(xPathFilters); + return transform; + } + + public XPathFilter createXPathFilter( + String filterType, + String xPathExpression, + Map namespaceDeclarations) { + XPathFilterImpl xPathFilter = new XPathFilterImpl(); + xPathFilter.setFilterType(filterType); + xPathFilter.setXPathExpression(xPathExpression); + xPathFilter.setNamespaceDelcarations(namespaceDeclarations); + return xPathFilter; + } + + public CheckResult createCheckResult(int code, NodeList info) { + CheckResultImpl checkResult = new CheckResultImpl(); + checkResult.setCode(code); + checkResult.setInfo(info); + return checkResult; + } + + public SignerInfo createSignerInfo( + X509Certificate signerCertificate, + boolean qualifiedCertificate, + boolean publicAuthority, + String publicAuthorityID) { + SignerInfoImpl signerInfo = new SignerInfoImpl(); + signerInfo.setSignerCertificate(signerCertificate); + signerInfo.setQualifiedCertificate(qualifiedCertificate); + signerInfo.setPublicAuthority(publicAuthority); + signerInfo.setPublicAuhtorityID(publicAuthorityID); + return signerInfo; + } + + public X509IssuerSerial createX509IssuerSerial( + String issuerName, + BigInteger serialNumber) { + X509IssuerSerialImpl x509IssuerSerial = new X509IssuerSerialImpl(); + x509IssuerSerial.setX509IssuerName(issuerName); + x509IssuerSerial.setX509SerialNumber(serialNumber); + return x509IssuerSerial; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignatureEnvironmentResponseImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignatureEnvironmentResponseImpl.java new file mode 100644 index 000000000..57d30ad3b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignatureEnvironmentResponseImpl.java @@ -0,0 +1,41 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.spss.api.xmlsign.SignatureEnvironmentResponse; + +/** + * Default implementation of <code>SignatureEnvironmentResponse</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class SignatureEnvironmentResponseImpl + implements SignatureEnvironmentResponse { + + /** The signature environment containing the XML signature. */ + private Element signatureEnvironment; + + /** + * Sets the XML structure which contains the signature. + * + * @param signatureEnvironment A general XML structure containing the signature. + */ + public void setSignatureEnvironment(Element signatureEnvironment) { + this.signatureEnvironment = signatureEnvironment; + } + + public Element getSignatureEnvironment() { + return signatureEnvironment; + } + + /** + * Gets the type of <code>CreateXMLSignatureResponseElement</code>. + * + * @return SIGNATURE_ENVIRONMENT_RESPONSE + */ + public int getResponseType() { + return SIGNATURE_ENVIRONMENT_RESPONSE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignatureManifestCheckParamsImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignatureManifestCheckParamsImpl.java new file mode 100644 index 000000000..5924f8447 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignatureManifestCheckParamsImpl.java @@ -0,0 +1,52 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams; + +/** + * Default implementation of <code>SignatureManifestCheckParams</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class SignatureManifestCheckParamsImpl + implements SignatureManifestCheckParams { + + /** Referential information. */ + private List referenceInfos; + /** Whether to return the signature source data. */ + private boolean returnReferenceInputData = true; + + /** + * Sets the referantial information. + * + * @param referenceInfos The referential information. + */ + public void setReferenceInfos(List referenceInfos) { + this.referenceInfos = + referenceInfos != null + ? Collections.unmodifiableList(new ArrayList(referenceInfos)) + : null; + } + + public List getReferenceInfos() { + return referenceInfos; + } + + /** + * Sets whether to return signature source data. + * + * @param returnReferenceInputData Whether to return signature source data. + */ + public void setReturnReferenceInputData(boolean returnReferenceInputData) { + this.returnReferenceInputData = returnReferenceInputData; + } + + public boolean getReturnReferenceInputData() { + return returnReferenceInputData; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignerInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignerInfoImpl.java new file mode 100644 index 000000000..277f1a008 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SignerInfoImpl.java @@ -0,0 +1,81 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.security.cert.X509Certificate; + +import at.gv.egovernment.moa.spss.api.common.SignerInfo; + +/** + * Default implementation of <code>SignerInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class SignerInfoImpl implements SignerInfo { + + /** The signer certificate. */ + private X509Certificate signerCertificate; + /** Determines, whether <code>signerCertificate</code> is a qualified + * certificate. */ + private boolean qualifiedCertificate; + /** Determines, whether <code>signerCertificate</code> is from a public + * authority. */ + private boolean publicAuthority; + /** The public authority ID of the <code>signerCertificate</code>. */ + private String publicAuthorityID; + + /** + * Sets the signer certificate. + * + * @param signerCertificate The signer certificate. + */ + public void setSignerCertificate(X509Certificate signerCertificate) { + this.signerCertificate = signerCertificate; + } + + public X509Certificate getSignerCertificate() { + return signerCertificate; + } + + /** + * Sets, whether the certificate contained in this object is qualified or not. + * + * @param qualifiedCertificate Is <code>true</code>, if the certificate is + * qualified, otherwise <code>false</code>. + */ + public void setQualifiedCertificate(boolean qualifiedCertificate) { + this.qualifiedCertificate = qualifiedCertificate; + } + + public boolean isQualifiedCertificate() { + return qualifiedCertificate; + } + + /** + * Sets, whether the certificate contained in this object is an + * e-government certificate or not. + * + * @param publicAuthority Is <code>true</code>, if the certificate is + * public authority certificate, otherwise <code>false</code>. + */ + public void setPublicAuthority(boolean publicAuthority) { + this.publicAuthority = publicAuthority; + } + + public boolean isPublicAuthority() { + return publicAuthority; + } + + /** + * Sets the public authority ID of the signer certificate. + * + * @param publicAuhtorityID The public authority ID of the signer certificate. + */ + public void setPublicAuhtorityID(String publicAuhtorityID) { + this.publicAuthorityID = publicAuhtorityID; + } + + public String getPublicAuhtorityID() { + return publicAuthorityID; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SingleSignatureInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SingleSignatureInfoImpl.java new file mode 100644 index 000000000..b50a65c68 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SingleSignatureInfoImpl.java @@ -0,0 +1,49 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo; + +/** + * @author Fatemeh Philippi + * @version $Id$ + */ +public class SingleSignatureInfoImpl implements SingleSignatureInfo { + + private List dataObjectInfos = new ArrayList(); + + private CreateSignatureInfo createSignatureInfo; + + private boolean securityLayerConform = true; + + public void setDataObjectInfos(List dataObjectInfos) { + this.dataObjectInfos = + dataObjectInfos != null + ? Collections.unmodifiableList(new ArrayList(dataObjectInfos)) + : null; + } + + public List getDataObjectInfos() { + return dataObjectInfos; + } + + public void setCreateSignatureInfo(CreateSignatureInfo createSignatureInfo) { + this.createSignatureInfo = createSignatureInfo; + } + + public CreateSignatureInfo getCreateSignatureInfo() { + return createSignatureInfo; + } + + public void setSecurityLayerConform(boolean securityLayerConform) { + this.securityLayerConform = securityLayerConform; + } + + public boolean isSecurityLayerConform() { + return securityLayerConform; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SupplementProfileExplicitImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SupplementProfileExplicitImpl.java new file mode 100644 index 000000000..78723fec2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SupplementProfileExplicitImpl.java @@ -0,0 +1,39 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileExplicit; + +/** + * Default implementation of <code>SupplementProfileExplicit</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class SupplementProfileExplicitImpl implements SupplementProfileExplicit { + + /** Supplemental information for verifying a signature. */ + private XMLDataObjectAssociation supplement; + + /** + * Sets the supplemental information for verifying a signature. + * + * @param supplement The supplemental information for verifying a signature. + */ + public void setSupplementProfile(XMLDataObjectAssociation supplement) { + this.supplement = supplement; + } + + public XMLDataObjectAssociation getSupplementProfile() { + return supplement; + } + + /** + * Gets the type of <code>SupplementProfile</code>. + * + * @return EXPLICIT_SUPPLEMENTPROFILE + */ + public int getSupplementProfileType() { + return EXPLICIT_SUPPLEMENTPROFILE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SupplementProfileIDImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SupplementProfileIDImpl.java new file mode 100644 index 000000000..320827fad --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/SupplementProfileIDImpl.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileID; + +/** + * Default implementation of <code>SupplementProfileID</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class SupplementProfileIDImpl implements SupplementProfileID { + /** The profile ID. */ + private String profileID; + + /** + * Sets the <code>SupplementProfile</code> profile ID. + * + * @param profileID The profile ID. + */ + public void setSupplementProfileID(String profileID) { + this.profileID = profileID; + } + + public String getSupplementProfileID() { + return profileID; + } + + /** + * Gets the type of <code>SupplementProfile</code>. + * + * @return ID_SUPPLEMENTPROFILE + */ + public int getSupplementProfileType() { + return ID_SUPPLEMENTPROFILE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformImpl.java new file mode 100644 index 000000000..51c7a543f --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformImpl.java @@ -0,0 +1,26 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.Transform; + +/** + * @author Fatemeh Philippi + * @version $Id$ + */ +public class TransformImpl implements Transform { + /** The URI identifying the transformation algorithm. */ + private String algorithmURI; + + /** + * Sets the URI identifying the transformation algorithm. + * + * @param algorithmURI The URI identifying the transformation algorithm. + */ + public void setAlgorithmURI(String algorithmURI) { + this.algorithmURI = algorithmURI; + } + + public String getAlgorithmURI() { + return algorithmURI; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterBinaryImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterBinaryImpl.java new file mode 100644 index 000000000..2901fb1bb --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterBinaryImpl.java @@ -0,0 +1,42 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.io.InputStream; + +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterBinary; + +/** + * Default implementation of <code>TransformParameterBinary</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class TransformParameterBinaryImpl + extends TransformParameterImpl + implements TransformParameterBinary { + + /** The binary content as a stream. */ + private InputStream binaryContent; + + /** + * Sets the binary content as a stream. + * + * @param binaryContent The binary content as a stream. + */ + public void setBinaryContent(InputStream binaryContent) { + this.binaryContent = binaryContent; + } + + public InputStream getBinaryContent() { + return binaryContent; + } + + /** + * Gets the <code>TransformParameter</code> type. + * + * @return BINARY_TRANSFORMPARAMETER + */ + public int getTransformParameterType() { + return BINARY_TRANSFORMPARAMETER; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterImpl.java new file mode 100644 index 000000000..9fe60638e --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterImpl.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.impl; + +/** + * Default base implementation of <code>TransformParameter</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class TransformParameterImpl { + /** An URI identifying the <code>TransformParameter</code>. */ + private String uri; + + /** + * Sets the URI identifying the <code>TransformParameter</code>. + * @param uri The URI identifying the <code>TransformParameter</code>. + */ + public void setURI(String uri) { + this.uri = uri; + } + + public String getURI() { + return uri; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterURIImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterURIImpl.java new file mode 100644 index 000000000..25449504c --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformParameterURIImpl.java @@ -0,0 +1,24 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterURI; + +/** + * Default implementation of <code>TransformParameterURI</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class TransformParameterURIImpl + extends TransformParameterImpl + implements TransformParameterURI { + + /** + * Gets the type of <code>TransformParameter</code>. + * + * @return URI_TRANSFORMPARAMETER + */ + public int getTransformParameterType() { + return URI_TRANSFORMPARAMETER; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformPatameterHashImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformPatameterHashImpl.java new file mode 100644 index 000000000..a7843e68c --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/TransformPatameterHashImpl.java @@ -0,0 +1,54 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterHash; + +/** + * Default implementation of <code>TransformParameterHash</code> + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class TransformPatameterHashImpl + extends TransformParameterImpl + implements TransformParameterHash { + + /** The method used to calculate the digest value. */ + private String digestMethod; + /** The digest value. */ + private byte[] digestValue; + + /** + * Sets method used to calculate the digest value. + * @param digestMethod The method used to calculate the digest value. + */ + public void setDigestMethod(String digestMethod) { + this.digestMethod = digestMethod; + } + + public String getDigestMethod() { + return digestMethod; + } + + /** + * Sets the digest value. + * + * @param digestValue The digest value. + */ + public void setDigestValue(byte[] digestValue) { + this.digestValue = digestValue; + } + + public byte[] getDigestValue() { + return digestValue; + } + + /** + * Gets the type of <code>TransformParameter</code>. + * + * @return HASH_TRANSFORMPARAMETER + */ + public int getTransformParameterType() { + return HASH_TRANSFORMPARAMETER; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSignatureRequestImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSignatureRequestImpl.java new file mode 100644 index 000000000..a3c37aaef --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSignatureRequestImpl.java @@ -0,0 +1,93 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.io.InputStream; +import java.util.Date; + +import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; + +/** + * Default implementation of <code>VerifyCMSSignatureRequest</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyCMSSignatureRequestImpl + implements VerifyCMSSignatureRequest { + + /** The indexes of the signatories whose signature should be verified. */ + private int[] signatories; + /** The profile ID of trusted certificates. */ + private String trustProfileId; + /** The data object necessary for signature verification. */ + private CMSDataObject dataObject; + /** The CMS signature to verify. */ + private InputStream cmsSignature; + /** The date for which to verify the signature. */ + private Date dateTime; + + /** + * Sets the indexes of the signatories whose signature should be verified. + * + * @param signatories The indexes of the signatories whose signature should be + * verified. + */ + public void setSignatories(int[] signatories) { + this.signatories = signatories; + } + + public int[] getSignatories() { + return signatories; + } + + /** + * Sets the date for which to verify the signature. + * + * @param dateTime The date for which to verify the signature. + */ + public void setDateTime(Date dateTime) { + this.dateTime = dateTime; + } + + public Date getDateTime() { + return dateTime; + } + + /** + * Sets the CMS signature to verify. + * @param signature The CMS signature to verify. + */ + public void setCMSSignature(InputStream signature) { + this.cmsSignature = signature; + + } + + public InputStream getCMSSignature() { + return cmsSignature; + } + + /** + * Sets the data object necessary for signature verification. + * @param dataObject The data object necessary for signature verification. + */ + public void setDataObject(CMSDataObject dataObject) { + this.dataObject = dataObject; + } + + public CMSDataObject getDataObject() { + return dataObject; + } + + /** + * Sets the profile ID of trusted certificates. + * @param trustProfileId The profile ID of trusted certificates. + */ + public void setTrustProfileId(String trustProfileId) { + this.trustProfileId = trustProfileId; + } + + public String getTrustProfileId() { + return trustProfileId; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSignatureResponseElementImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSignatureResponseElementImpl.java new file mode 100644 index 000000000..40dc04683 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSignatureResponseElementImpl.java @@ -0,0 +1,62 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; + +/** + * Default implementation of <code>VerifyCMSSignatureResponseElement</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyCMSSignatureResponseElementImpl + implements VerifyCMSSignatureResponseElement { + + /** Information about the signer certificate. */ + private SignerInfo signerInfo; + /** Information about the signature check. */ + private CheckResult signatureCheck; + /** Information about the certificate check. */ + private CheckResult certificateCheck; + + /** + * Sets a SignerInfo element according to CMS. + * + * @param signerInfo The SignerInfo element according to CMS. + */ + public void setSignerInfo(SignerInfo signerInfo) { + this.signerInfo = signerInfo; + } + + public SignerInfo getSignerInfo() { + return signerInfo; + } + + /** + * Sets a result of the signature verification. + * + * @param signatureCheck The result of the signature verification. + */ + public void setSignatureCheck(CheckResult signatureCheck) { + this.signatureCheck = signatureCheck; + } + + public CheckResult getSignatureCheck() { + return signatureCheck; + } + + /** + * Sets a result of the certificate verification. + * + * @param certificateCheck The result of the certificate verification. + */ + public void setCertificateCheck(CheckResult certificateCheck) { + this.certificateCheck = certificateCheck; + } + + public CheckResult getCertificateCheck() { + return certificateCheck; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSinatureResponseImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSinatureResponseImpl.java new file mode 100644 index 000000000..f258380e0 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyCMSSinatureResponseImpl.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; + +/** + * Default implementation of <code>VerifyCMSSignatureResponse</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyCMSSinatureResponseImpl + implements VerifyCMSSignatureResponse { + + /** The elements contained in the response. */ + private List responseElements; + + /** + * Sets the elements contained in the response. + * + * @param responseElements The elements contained in the response. + */ + public void setResponseElements(List responseElements) { + this.responseElements = + responseElements != null + ? Collections.unmodifiableList(new ArrayList(responseElements)) + : null; + } + + public List getResponseElements() { + return responseElements; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifySignatureInfoImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifySignatureInfoImpl.java new file mode 100644 index 000000000..2653e2fd2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifySignatureInfoImpl.java @@ -0,0 +1,47 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation; + +/** + * Default implementation of <code>VerifySignatureInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifySignatureInfoImpl implements VerifySignatureInfo { + /** The location of the signature to be verified. */ + private VerifySignatureLocation verifySignatureLocation; + /** The environment containing the signature to be verified. */ + private Content verifySignatureEnvironment; + + /** + * Sets the location of the signature to be verified. + * + * @param verifySignatureLocation The location of the signature to be + * verified. + */ + public void setVerifySignatureLocation(VerifySignatureLocation verifySignatureLocation) { + this.verifySignatureLocation = verifySignatureLocation; + } + + public VerifySignatureLocation getVerifySignatureLocation() { + return verifySignatureLocation; + } + + /** + * Sets the signature environment containing the signature to be verified. + * + * @param verifySignatureEnvironment The signature environment containing the + * signature to be verified. + */ + public void setVerifySignatureEnvironment(Content verifySignatureEnvironment) { + this.verifySignatureEnvironment = verifySignatureEnvironment; + } + + public Content getVerifySignatureEnvironment() { + return verifySignatureEnvironment; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifySignatureLocationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifySignatureLocationImpl.java new file mode 100644 index 000000000..933e42987 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifySignatureLocationImpl.java @@ -0,0 +1,15 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation; + +/** + * Default implementation of <code>VerifySignatureLocation</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifySignatureLocationImpl + extends ElementSelectorImpl + implements VerifySignatureLocation { + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsDataImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsDataImpl.java new file mode 100644 index 000000000..594f9c246 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsDataImpl.java @@ -0,0 +1,36 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; + +/** + * Default implementation of <codeReferenceInfo</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyTransformsDataImpl implements ReferenceInfo { + /** Information about the transformations contained in the signature. */ + private List verifyTransformsInfoProfiles; + + /** + * Sets the information about the transformations contained in the signature. + * + * @param verifyTransformsInfoProfiles The profiles containing transformation + * information. + */ + public void setVerifyTransformsInfoProfiles(List verifyTransformsInfoProfiles) { + this.verifyTransformsInfoProfiles = + verifyTransformsInfoProfiles != null + ? Collections.unmodifiableList( + new ArrayList(verifyTransformsInfoProfiles)) + : null; + } + + public List getVerifyTransformsInfoProfiles() { + return verifyTransformsInfoProfiles; + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsInfoProfileExplicitImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsInfoProfileExplicitImpl.java new file mode 100644 index 000000000..d9a864499 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsInfoProfileExplicitImpl.java @@ -0,0 +1,61 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit; + +/** + * Default implementation of <code>VerifyTransformsInfoProfileExplicit</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyTransformsInfoProfileExplicitImpl + implements VerifyTransformsInfoProfileExplicit { + + /** The transforms contained in this profile. */ + private List transforms; + /** Additional information for the transforms. */ + private List transformParameters = new ArrayList(); + + /** + * Sets the transforms contained in this profile. + * + * @param transforms The transforms contained in this profile. + */ + public void setTransforms(List transforms) { + this.transforms = + transforms != null + ? Collections.unmodifiableList(new ArrayList(transforms)) + : null; + } + + public List getTransforms() { + return transforms; + } + + /** + * Sets additional information for the transforms. + * + * @param transformParameters Additional information for the transforms. + */ + public void setTransformParameters(List transformParameters) { + this.transformParameters = new ArrayList(transformParameters); + } + + public List getTransformParameters() { + return transformParameters; + } + + /** + * Gets the type of <code>VerifyTransformsInfoProfile</code>. + * + * @return EXPLICIT_VERIFYTRANSFORMSINFOPROFILE + */ + public int getVerifyTransformsInfoProfileType() { + return EXPLICIT_VERIFYTRANSFORMSINFOPROFILE; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsInfoProfileIDImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsInfoProfileIDImpl.java new file mode 100644 index 000000000..fb1f10cea --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyTransformsInfoProfileIDImpl.java @@ -0,0 +1,38 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileID; + +/** + * Default implementation of <code>VerifyTransformsInfoProfileID</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyTransformsInfoProfileIDImpl implements VerifyTransformsInfoProfileID { + + /** The profile ID. */ + private String verifyTransformsInfoProfileID; + + /** + * Sets the profile ID. + * + * @param profileID The profile ID. + */ + public void setVerifyTransformsInfoProfileID(String profileID) { + this.verifyTransformsInfoProfileID = profileID; + } + + public String getVerifyTransformsInfoProfileID() { + return verifyTransformsInfoProfileID; + } + + /** + * Gets the type of <code>VerifyTransformsInfoProfile</code>. + * + * @return ID_VERIFYTRANSFORMSINFOPROFILE + */ + public int getVerifyTransformsInfoProfileType() { + return ID_VERIFYTRANSFORMSINFOPROFILE; + } + +}
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyXMLSignatureRequestImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyXMLSignatureRequestImpl.java new file mode 100644 index 000000000..26d7def4c --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyXMLSignatureRequestImpl.java @@ -0,0 +1,113 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; + +/** + * Default implementation of <code>VerifyXMLSignatureRequest</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyXMLSignatureRequestImpl + implements VerifyXMLSignatureRequest { + /** Date and time for signature verification. */ + private Date dateTime; + /** The signature to be verified. */ + private VerifySignatureInfo verifySignatureInfo; + /** Supplemental information about the singature. */ + private List supplementProfiles; + /** Additional parameters for checking the signature manifest. */ + private SignatureManifestCheckParams signatureManifestCheckParams; + /** Whether to return the hash input data. */ + private boolean returnHashInputData; + /** The profile ID of the trust profile containing the trusted certificates. + */ + private String trustProfileId; + + /** + * Sets the date and time for signature verification. + * + * @param dateTime The date and time for signature verification. + */ + public void setDateTime(Date dateTime) { + this.dateTime = dateTime; + } + + public Date getDateTime() { + return dateTime; + } + + /** + * Sets the signature to be verified. + * + * @param signatureInfo The signature to be verified. + */ + public void setSignatureInfo(VerifySignatureInfo signatureInfo) { + this.verifySignatureInfo = signatureInfo; + } + + public VerifySignatureInfo getSignatureInfo() { + return verifySignatureInfo; + } + + /** + * Sets supplemental information about the singature. + * @param supplementProfiles + */ + public void setSupplementProfiles(List supplementProfiles) { + this.supplementProfiles = + supplementProfiles != null + ? Collections.unmodifiableList(new ArrayList(supplementProfiles)) + : null; + } + + public List getSupplementProfiles() { + return supplementProfiles; + } + + /** + * Sets supplemental information about the singature. + * @param params Supplemental information about the singature. + */ + public void setSignatureManifestCheckParams(SignatureManifestCheckParams params) { + this.signatureManifestCheckParams = params; + } + + public SignatureManifestCheckParams getSignatureManifestCheckParams() { + return signatureManifestCheckParams; + } + + /** + * Sets whether to return hash input data. + * + * @param returnSignedData Whether to return hash input data. + */ + public void setReturnHashInputData(boolean returnSignedData) { + this.returnHashInputData = returnSignedData; + } + + public boolean getReturnHashInputData() { + return returnHashInputData; + } + + /** + * Sets the profile ID of trusted certificates. + * + * @param trustProfileId The profile ID of trusted certificates. + */ + public void setTrustProfileId(String trustProfileId) { + this.trustProfileId = trustProfileId; + } + + public String getTrustProfileId() { + return trustProfileId; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyXMLSignatureResponseImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyXMLSignatureResponseImpl.java new file mode 100644 index 000000000..f163013c1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/VerifyXMLSignatureResponseImpl.java @@ -0,0 +1,134 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; + +/** + * @author Fatemeh Philippi + * @version $Id$ + */ +public class VerifyXMLSignatureResponseImpl + implements VerifyXMLSignatureResponse { + + /** Information about the signer certificate. */ + private SignerInfo signerInfo; + /** The hash input data objects. */ + private List hashInputDatas = new ArrayList(); + /** The reference input data objects. */ + private List referenceInputDatas = new ArrayList(); + /** Information about the signature check. */ + private ReferencesCheckResult signatureCheck; + /** Information about the signature manifest check. */ + private ReferencesCheckResult signatureManifestCheck; + /** Information about the XMLDsig manifest check. */ + private List xmlDsigManifestChecks = new ArrayList(); + /** Information about the certificate check. */ + private CheckResult certificateCheck; + + /** + * Sets information about the signer certificate. + * + * @param signerInfo Information about the signer certificate. + */ + public void setSignerInfo(SignerInfo signerInfo) { + this.signerInfo = signerInfo; + } + + public SignerInfo getSignerInfo() { + return signerInfo; + } + + /** + * Sets data signed by the signatory. + * + * @param hashInputDatas The signed datas. + */ + public void setHashInputDatas(List hashInputDatas) { + this.hashInputDatas = + hashInputDatas != null + ? Collections.unmodifiableList(new ArrayList(hashInputDatas)) + : null; + } + + public List getHashInputDatas() { + return hashInputDatas; + } + + /** + * Sets the source data elements. + * + * @param referenceInputDatas The source data elements. + */ + public void setReferenceInputDatas(List referenceInputDatas) { + this.referenceInputDatas = + referenceInputDatas != null + ? Collections.unmodifiableList(new ArrayList(referenceInputDatas)) + : null; + } + + public List getReferenceInputDatas() { + return referenceInputDatas; + } + + /** + * Sets the result of the signature verification. + * + * @param signatureCheck The result of the signature verification. + */ + public void setSignatureCheck(ReferencesCheckResult signatureCheck) { + this.signatureCheck = signatureCheck; + } + + public ReferencesCheckResult getSignatureCheck() { + return signatureCheck; + } + + /** + * Sets the result of the signature manifest verification. + * + * @param signatureManifestCheck The result of the signature manifest verification. + */ + public void setSignatureManifestCheck(ReferencesCheckResult signatureManifestCheck) { + this.signatureManifestCheck = signatureManifestCheck; + } + + public ReferencesCheckResult getSignatureManifestCheck() { + return signatureManifestCheck; + } + + /** + * Sets the result of the certification verification. + * + * @param certificateCheck The result of the certificate verification. + */ + public void setCertificateCheck(CheckResult certificateCheck) { + this.certificateCheck = certificateCheck; + } + + public CheckResult getCertificateCheck() { + return certificateCheck; + } + + /** + * Sets the XMLDSigManifestChecks. + * + * @param xmlDsigManifestChecks The XMLDSigManifestChecks. + */ + public void setXMLDsigManifestChecks(List xmlDsigManifestChecks) { + this.xmlDsigManifestChecks = + xmlDsigManifestChecks != null + ? Collections.unmodifiableList(new ArrayList(xmlDsigManifestChecks)) + : null; + } + + public List getXMLDsigManifestChecks() { + return xmlDsigManifestChecks; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/X509IssuerSerialImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/X509IssuerSerialImpl.java new file mode 100644 index 000000000..e6d644fd9 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/X509IssuerSerialImpl.java @@ -0,0 +1,45 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.math.BigInteger; + +import at.gv.egovernment.moa.spss.api.common.X509IssuerSerial; + +/** + * Default implementation of <code>X509IssuerSerial</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class X509IssuerSerialImpl implements X509IssuerSerial { + /** The certificate serial number. */ + private BigInteger x509SerialNumber; + /** The certificate issuer DN. */ + private String x509IssuerName; + + /** + * Sets the issuer distinguished name. + * + * @param x509IssuerName The issuer distinguished name. + */ + public void setX509IssuerName(String x509IssuerName) { + this.x509IssuerName = x509IssuerName; + } + + public String getX509IssuerName() { + return x509IssuerName; + } + + /** + * Sets the certificate serial number. + * + * @param x509SerialNumber The issuer serial number. + */ + public void setX509SerialNumber(BigInteger x509SerialNumber) { + this.x509SerialNumber = x509SerialNumber; + } + + public BigInteger getX509SerialNumber() { + return x509SerialNumber; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XMLDataObjectAssociationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XMLDataObjectAssociationImpl.java new file mode 100644 index 000000000..b603c3367 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XMLDataObjectAssociationImpl.java @@ -0,0 +1,45 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; + +/** + * Default implementation of <code>XMLDataObjectAssociation</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class XMLDataObjectAssociationImpl implements XMLDataObjectAssociation { + + /** Meta information about the <code>Content</code> object. */ + private MetaInfo metaInfo; + /** The actual data contained in this object. */ + private Content content; + + /** + * Sets meta information about the <code>Content</code> object. + * @param metaInfo Meta information about the <code>Content</code> object. + */ + public void setMetaInfo(MetaInfo metaInfo) { + this.metaInfo = metaInfo; + } + + public MetaInfo getMetaInfo() { + return metaInfo; + } + + /** + * Sets the actual data contained in this object. + * + * @param content The actual data contained in this object. + */ + public void setContent(Content content) { + this.content = content; + } + + public Content getContent() { + return content; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathFilter2TransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathFilter2TransformImpl.java new file mode 100644 index 000000000..a96a8f161 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathFilter2TransformImpl.java @@ -0,0 +1,43 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.ArrayList; +import java.util.List; + +import at.gv.egovernment.moa.spss.api.common.XPathFilter2Transform; + +/** + * Default implementation of <code>XPathFilter2Transform</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class XPathFilter2TransformImpl + extends TransformImpl + implements XPathFilter2Transform { + + /** The XPath filters. */ + private List filters; + + /** + * Create a new <code>XPathFilter2TransformImpl</code> object. + */ + public XPathFilter2TransformImpl() { + setAlgorithmURI(XPATH_FILTER2); + } + + /** + * Sets the XPath filters contained in this + * <code>XPathFilter2Transform</code>. + * + * @param filters The XPath filters contained in this + * <code>XPathFilter2Transform</code>. + */ + public void setFilters(List filters) { + this.filters = new ArrayList(filters); + } + + public List getFilters() { + return filters; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathFilterImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathFilterImpl.java new file mode 100644 index 000000000..72d91bc58 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathFilterImpl.java @@ -0,0 +1,64 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.HashMap; +import java.util.Map; + +import at.gv.egovernment.moa.spss.api.common.XPathFilter; + +/** + * Default implementation of <code>XPathFilter</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class XPathFilterImpl implements XPathFilter { + /** The type of filter. */ + private String filterType; + /** The XPath expression of the filter. */ + private String xPathExpression; + /** The namespace prefix to URI mapping to while evaluating the XPath + * expression. */ + private Map namespaceDeclarations = new HashMap(); + + /** + * Sets the type of filter. + * + * @param filterType The type of filter. + */ + public void setFilterType(String filterType) { + this.filterType = filterType; + } + + public String getFilterType() { + return filterType; + } + + /** + * Sets the XPath expression of the filter. + * + * @param xPathExpression The XPath expression of the filter. + */ + public void setXPathExpression(String xPathExpression) { + this.xPathExpression = xPathExpression; + } + + public String getXPathExpression() { + return xPathExpression; + } + + /** + * Sets the namespace prefix to URI mapping to while evaluating the XPath + * expression. + * + * @param namespaceDeclarations The namespace prefix to URI mapping to while + * evaluating the XPath expression. + */ + public void setNamespaceDelcarations(Map namespaceDeclarations) { + this.namespaceDeclarations = namespaceDeclarations; + } + + public Map getNamespaceDeclarations() { + return namespaceDeclarations; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathTransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathTransformImpl.java new file mode 100644 index 000000000..1c9817ecc --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XPathTransformImpl.java @@ -0,0 +1,59 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import java.util.HashMap; +import java.util.Map; + +import at.gv.egovernment.moa.spss.api.common.XPathTransform; + +/** + * Default implementation of <code>XPathTransform</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class XPathTransformImpl + extends TransformImpl + implements XPathTransform { + + /** The XPath expression to evaluate. */ + private String xPathExpression; + /** The namespace prefix to URI mapping to while evaluating the XPath + * expression. */ + private Map namespaceDeclarations = new HashMap(); + + /** + * Create a new <code>XPathTransformImpl</code> object. + */ + public XPathTransformImpl() { + setAlgorithmURI(XPATH); + } + + /** + * Sets the XPath expression to evaluate. + * + * @param xPathExpression The XPath expression to evaluate. + */ + public void setXPathExpression(String xPathExpression) { + this.xPathExpression = xPathExpression; + } + + public String getXPathExpression() { + return xPathExpression; + } + + /** + * Sets the namespace prefix to URI mapping to while evaluating the XPath + * expression. + * + * @param namespaceDeclarations The namespace prefix to URI mapping to while + * evaluating the XPath expression. + */ + public void setNamespaceDelcarations(Map namespaceDeclarations) { + this.namespaceDeclarations = namespaceDeclarations; + } + + public Map getNamespaceDeclarations() { + return namespaceDeclarations; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XSLTransformImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XSLTransformImpl.java new file mode 100644 index 000000000..c6ddc0fd6 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/impl/XSLTransformImpl.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.spss.api.impl; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.spss.api.common.XSLTTransform; + +/** + * Default implementation of <code>XSLTTransform</code>. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class XSLTransformImpl extends TransformImpl implements XSLTTransform { + /** The XSLT stylesheet to apply. */ + private Element styleSheet; + + /** + * Create a new <code>XSLTransformImpl</code> object. + */ + public XSLTransformImpl() { + setAlgorithmURI(XSLT); + } + + /** + * Sets the XSLT stylesheet to apply. + * + * @param styleSheet The XSLT stylesheet to apply. + */ + public void setStylesheet(Element styleSheet) { + this.styleSheet = styleSheet; + } + + public Element getStylesheet() { + return styleSheet; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureRequestParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureRequestParser.java new file mode 100644 index 000000000..319d3ac9d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureRequestParser.java @@ -0,0 +1,288 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.traversal.NodeIterator; + +import at.gv.egovernment.moa.util.BoolUtils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo; + +/** + * A parser to parse <code>CreateXMLSignatureRequest</code> DOM trees into + * <code>CreateXMLSignatureRequest</code> API objects. + * + * @author Patrick Peck + * @version $Id$ + */ +public class CreateXMLSignatureRequestParser { + + // + // XPath expresssions to select elements in the CreateXMLSignatureRequest + // + private static final String MOA = Constants.MOA_PREFIX + ":"; + private static final String KEY_IDENTIFIER_XPATH = + "/" + MOA + "CreateXMLSignatureRequest/" + MOA + "KeyIdentifier"; + private static final String SINGLE_SIGNATURE_INFO_XPATH = + "/" + MOA + "CreateXMLSignatureRequest/" + MOA + "SingleSignatureInfo"; + private static final String DATA_OBJECT_INFO_XPATH = MOA + "DataObjectInfo"; + private static final String DATA_OBJECT_XPATH = MOA + "DataObject"; + private static final String CREATE_SIGNATURE_INFO_XPATH = + MOA + "CreateSignatureInfo"; + private static final String CREATE_TRANSFORMS_INFO_PROFILE_XPATH = + (MOA + "CreateTransformsInfoProfile | ") + + (MOA + "CreateTransformsInfoProfileID"); + private static final String CREATE_SIGNATURE_ENVIRONMENT_XPATH = + MOA + "CreateSignatureEnvironment"; + private static final String CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH = + (MOA + "CreateSignatureEnvironmentProfile | ") + + (MOA + "CreateSignatureEnvironmentProfileID"); + private static final String SL_CONFORM_ATTR_NAME = "SecurityLayerConformity"; + + /** The factory to create API objects. */ + private SPSSFactory factory; + + /** + * Create a new <code>CreateXMLSignatureRequestParser</code>. + */ + public CreateXMLSignatureRequestParser() { + this.factory = SPSSFactory.getInstance(); + } + + /** + * Parse a <code>CreateXMLSignatureRequest</code> DOM element, as defined + * by the MOA schema. + * + * @param requestElem The <code>CreateXMLSignatureRequest</code> to parse. The + * request must have been successfully parsed against the schema for this + * method to succeed. + * @return A <code>CreateXMLSignatureRequest</code> API object containing + * the data from the DOM element. + * @throws MOAApplicationException An error occurred parsing the request. + */ + public CreateXMLSignatureRequest parse(Element requestElem) + throws MOAApplicationException { + + List singleSignatureInfos = parseSingleSignatureInfos(requestElem); + String keyIdentifier = + XPathUtils.getElementValue(requestElem, KEY_IDENTIFIER_XPATH, null); + + return factory.createCreateXMLSignatureRequest( + keyIdentifier, + singleSignatureInfos); + } + + /** + * Parse all <code>SingleSignatureInfo</code> elements of the + * <code>CreateXMLSignatureRequest</code>. + * + * @param requestElem The <code>CreateXMLSignatureRequest</code> to parse. + * @return A <code>List</code> of <code>SingleSignatureInfo</code> API + * objects. + * @throws MOAApplicationException An error occurred parsing on of the + * <code>SingleSignatureInfo</code> elements. + */ + private List parseSingleSignatureInfos(Element requestElem) + throws MOAApplicationException { + + List singleSignatureInfos = new ArrayList(); + NodeIterator sigInfoElems = + XPathUtils.selectNodeIterator(requestElem, SINGLE_SIGNATURE_INFO_XPATH); + Element sigInfoElem; + + while ((sigInfoElem = (Element) sigInfoElems.nextNode()) != null) { + singleSignatureInfos.add(parseSingleSignatureInfo(sigInfoElem)); + } + + return singleSignatureInfos; + } + + /** + * Parse a <code>SingleSignatureInfo</code> DOM element. + * + * @param sigInfoElem The <code>SingleSignatureInfo</code> DOM element to + * parse. + * @return A <code>SingleSignatureInfo</code> API object containing the + * information of <code>sigInfoElem</code>. + * @throws MOAApplicationException An error occurred parsing the + * <code>SingleSignatureInfo</code>. + */ + private SingleSignatureInfo parseSingleSignatureInfo(Element sigInfoElem) + throws MOAApplicationException { + + List dataObjectInfos = parseDataObjectInfos(sigInfoElem); + CreateSignatureInfo createSignatureInfo = + parseCreateSignatureInfo(sigInfoElem); + boolean securityLayerConform; + + if (sigInfoElem.hasAttribute(SL_CONFORM_ATTR_NAME)) { + securityLayerConform = + BoolUtils.valueOf(sigInfoElem.getAttribute(SL_CONFORM_ATTR_NAME)); + } else { + securityLayerConform = true; + } + + return factory.createSingleSignatureInfo( + dataObjectInfos, + createSignatureInfo, + securityLayerConform); + } + + /** + * Parse the <code>DataObjectInfo</code> DOM elements contained in the given + * <code>SingleSignatureInfo</code> DOM element. + * + * @param sigInfoElem The <code>SingleSignatureInfo</code> DOM element + * whose <code>DataObjectInfo</code>s to parse. + * @return A <code>List</code> of <code>DataObjectInfo</code> API objects + * containing the data from the <code>DataObjectInfo</code> DOM elements. + * @throws MOAApplicationException An error occurred parsing one of the + * <code>DataObjectInfo</code>s. + */ + private List parseDataObjectInfos(Element sigInfoElem) + throws MOAApplicationException { + + List dataObjectInfos = new ArrayList(); + NodeIterator dataObjInfoElems = + XPathUtils.selectNodeIterator(sigInfoElem, DATA_OBJECT_INFO_XPATH); + Element dataObjInfoElem; + + while ((dataObjInfoElem = (Element) dataObjInfoElems.nextNode()) != null) { + dataObjectInfos.add(parseDataObjectInfo(dataObjInfoElem)); + } + return dataObjectInfos; + } + + /** + * Parse a <code>DataObjectInfo</code> DOM element. + * + * @param dataObjInfoElem The <code>DataObjectInfo</code> DOM element to + * parse. + * @return A <code>DataObjectInfo</code> API element containing the data + * from <code>dataObjInfoElem</code>. + * @throws MOAApplicationException An error occurred parsing the + * <code>DataObjectInfo</code>. + */ + private DataObjectInfo parseDataObjectInfo(Element dataObjInfoElem) + throws MOAApplicationException { + + String structure = dataObjInfoElem.getAttribute("Structure"); + Element dataObjectElem = + (Element) XPathUtils.selectSingleNode(dataObjInfoElem, DATA_OBJECT_XPATH); + Content dataObject = RequestParserUtils.parseContent(dataObjectElem); + CreateTransformsInfoProfile createTransformsInfoProfile = + parseCreateTransformsInfoProfile(dataObjInfoElem); + boolean childOfManifest; + + if (dataObjInfoElem.hasAttribute("ChildOfManifest")) { + childOfManifest = + BoolUtils.valueOf(dataObjInfoElem.getAttribute("ChildOfManifest")); + } else { + childOfManifest = false; + } + + return factory.createDataObjectInfo( + structure, + childOfManifest, + dataObject, + createTransformsInfoProfile); + } + + /** + * Parse a <code>CreateTransformsInfoProfile</code> DOM element. + * + * @param dataObjInfoElem The <code>DataObjectInfo</code> DOM element + * containing the <code>CreateTransformsInfoProfile</code>. + * @return The <code>CreateTransformsInfoProfile</code> API object containing + * the profile found in <code>dataObjInfoElem</code>. + * @throws MOAApplicationException An error occurred parsing the + * <code>CreateTransformsInfoProfile</code>. + */ + private CreateTransformsInfoProfile parseCreateTransformsInfoProfile(Element dataObjInfoElem) + throws MOAApplicationException { + + Element profileElem = + (Element) XPathUtils.selectSingleNode( + dataObjInfoElem, + CREATE_TRANSFORMS_INFO_PROFILE_XPATH); + + if ("CreateTransformsInfoProfile".equals(profileElem.getLocalName())) { + ProfileParser profileParser = new ProfileParser(); + return profileParser.parseCreateTransformsInfoProfile(profileElem); + + } else { + String profileID = DOMUtils.getText(profileElem); + return factory.createCreateTransformsInfoProfile(profileID); + } + } + + /** + * Parse the <code>CreateSignatureInfo</code> DOM element contained in + * a <code>SingleSignatureInfo</code>. + * + * @param sigInfoElem The <code>SingleSignatureInfo</code> DOM element + * containing the <code>CreateSignatureInfo</code> to be parsed. + * @return A <code>CreateSignatureInfo</code> API object containing the + * data from the <code>CreateSignatureInfo</code> DOM element, or + * <code>null</code>, if none was found. + */ + private CreateSignatureInfo parseCreateSignatureInfo(Element sigInfoElem) { + Element createInfoElem = + (Element) XPathUtils.selectSingleNode( + sigInfoElem, + CREATE_SIGNATURE_INFO_XPATH); + + if (createInfoElem != null) { + Element environmentElem = + (Element) XPathUtils.selectSingleNode( + createInfoElem, + CREATE_SIGNATURE_ENVIRONMENT_XPATH); + Content environment = RequestParserUtils.parseContent(environmentElem); + CreateSignatureEnvironmentProfile environmentProfile = + parseCreateSignatureEnvironmentProfile(createInfoElem); + + return factory.createCreateSignatureInfo(environment, environmentProfile); + } else { + return null; + } + } + + /** + * Parse the <code>CreateSignatureEnvironmentProfile</code> contained in + * the given <code>CreateSignatureInfo</code> DOM element. + * + * @param createInfoElem <code>CreateSignatureInfo</code> DOM element to + * parse. + * @return The <code>CreateSignatureEnvironmentProfile</code> contained + * in the given <code>CreateSignatureInfo</code> DOM element.. + */ + private CreateSignatureEnvironmentProfile parseCreateSignatureEnvironmentProfile(Element createInfoElem) { + Element profileElem = + (Element) XPathUtils.selectSingleNode( + createInfoElem, + CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH); + + if ("CreateSignatureEnvironmentProfile" + .equals(profileElem.getLocalName())) { + ProfileParser profileParser = new ProfileParser(); + return profileParser.parseCreateSignatureEnvironmentProfile(profileElem); + } else { + String profileID = DOMUtils.getText(profileElem); + return factory.createCreateSignatureEnvironmentProfile(profileID); + } + } + +}
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureResponseBuilder.java new file mode 100644 index 000000000..eec9c4882 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureResponseBuilder.java @@ -0,0 +1,119 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.util.Iterator; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egovernment.moa.util.Constants; + +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.SignatureEnvironmentResponse; + +/** + * Convert a <code>CreateXMLSignatureResponse</code> API object into its + * XML representation, according to the MOA XML schema. + * + * @author Patrick Peck + * @version $Id$ + */ +public class CreateXMLSignatureResponseBuilder { + private static final String MOA_NS_URI = Constants.MOA_NS_URI; + + /** The XML document containing the response element. */ + private Document responseDoc; + /** The response <code>CreateXMLSignatureResponse</code> DOM element. */ + private Element responseElem; + + /** + * Create a new <code>CreateXMLSignatureResponseBuilder</code>: + * + * @throws MOASystemException An error occurred setting up the resulting + * XML document. + */ + public CreateXMLSignatureResponseBuilder() throws MOASystemException { + responseDoc = + ResponseBuilderUtils.createResponse("CreateXMLSignatureResponse"); + responseElem = responseDoc.getDocumentElement(); + } + + /** + * Build a document containing a <code>CreateXMLSignatureResponse</code> + * DOM element being the XML representation of the given + * <code>CreateXMLSignatureResponse</code> API object. + * + * @param response The <code>CreateXMLSignatureResponse</code> to convert + * to XML. + * @return A document containing the <code>CreateXMLSignatureResponse</code> + * DOM element. + */ + public Document build(CreateXMLSignatureResponse response) { + Iterator iter; + + for (iter = response.getResponseElements().iterator(); iter.hasNext();) { + CreateXMLSignatureResponseElement responseElement = + (CreateXMLSignatureResponseElement) iter.next(); + + switch (responseElement.getResponseType()) { + case CreateXMLSignatureResponseElement.SIGNATURE_ENVIRONMENT_RESPONSE : + SignatureEnvironmentResponse envResponse = + (SignatureEnvironmentResponse) responseElement; + addSignatureEnvironment(envResponse); + break; + + case CreateXMLSignatureResponseElement.ERROR_RESPONSE : + ErrorResponse errorResponse = (ErrorResponse) responseElement; + addErrorResponse(errorResponse); + break; + } + + } + + return responseDoc; + } + + /** + * Add a <code>SignatureEnvironment</code> element to the response. + * + * @param envResponse The content to put under the + * <code>SignatureEnvironment</code> element. This should either be a + * <code>dsig:Signature</code> element (in case of a detached signature) or + * the signature environment containing the signature (in case of + * an enveloping signature). + */ + private void addSignatureEnvironment(SignatureEnvironmentResponse envResponse) { + Element content = envResponse.getSignatureEnvironment(); + Node importedSignature = responseDoc.importNode(content, true); + Element signatureEnvironment = + responseDoc.createElementNS(MOA_NS_URI, "SignatureEnvironment"); + signatureEnvironment.appendChild(importedSignature); + responseElem.appendChild(signatureEnvironment); + } + + /** + * Add a <code>ErrorResponse</code> element to the response. + * + * @param errorResponse The API object containing the information to put into + * the <code>ErrorResponse</code> DOM element. + */ + private void addErrorResponse(ErrorResponse errorResponse) { + Element errorElem = + responseDoc.createElementNS(MOA_NS_URI, "ErrorResponse"); + Element errorCodeElem = + responseDoc.createElementNS(MOA_NS_URI, "ErrorCode"); + Element infoElem = responseDoc.createElementNS(MOA_NS_URI, "Info"); + String errorCodeStr = Integer.toString(errorResponse.getErrorCode()); + + errorCodeElem.appendChild(responseDoc.createTextNode(errorCodeStr)); + errorElem.appendChild(errorCodeElem); + infoElem.appendChild(responseDoc.createTextNode(errorResponse.getInfo())); + errorElem.appendChild(errorCodeElem); + errorElem.appendChild(infoElem); + responseElem.appendChild(errorElem); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ProfileParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ProfileParser.java new file mode 100644 index 000000000..66c08e0ab --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ProfileParser.java @@ -0,0 +1,285 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.traversal.NodeIterator; + +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile; + +/** + * Parse the various profile elements contained in the MOA web service requests + * and given as separate files in the MOA configuration. + * + * The profiles parsed must be schema valid according to the MOA XML schema. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ProfileParser { + + // + // XPath expressions to select parts of the profiles + // + private static final String MOA = Constants.MOA_PREFIX + ":"; + private static final String DSIG = Constants.DSIG_PREFIX + ":"; + private static final String CREATE_TRANSFORMS_XPATH = + MOA + "CreateTransformsInfo/" + DSIG + "Transforms"; + private static final String FINAL_DATA_META_INFO_XPATH = + MOA + "CreateTransformsInfo/" + MOA + "FinalDataMetaInfo"; + private static final String CREATE_SIGNATURE_LOCATION_XPATH = + MOA + "CreateSignatureLocation"; + private static final String SUPPLEMENT_XPATH = MOA + "Supplement"; + private static final String VERIFY_TRANSFORMS_XPATH = DSIG + "Transforms"; + private static final String TRANSFORM_PARAMETER_XPATH = + MOA + "TransformParameter"; + private static final String TRANSFORM_PARAMETER_CONTENT_XPATH = + MOA + "Base64Content | " + MOA + "Hash"; + private static final String DIGEST_METHOD_XPATH = DSIG + "DigestMethod"; + private static final String DIGEST_VALUE_XPATH = DSIG + "DigestValue"; + + /** The factory used to create API objects. */ + private SPSSFactory factory = SPSSFactory.getInstance(); + + /** + * Parse a <code>CreateTransformsInfoProfile</code> DOM element. + * + * @param profileElem The <code>CreateTransformsInfoProfile</code> element + * to parse. + * @return The <code>CreateTransformsInfoProfile</code> API object containing + * the data from the <code>profileElem</code>. + * @throws MOAApplicationException An error occurred parsing the DOM element. + */ + public CreateTransformsInfoProfile parseCreateTransformsInfoProfile(Element profileElem) + throws MOAApplicationException { + CreateTransformsInfo createTransformsInfo = + parseCreateTransformsInfo(profileElem); + List supplements = parseSupplements(profileElem); + + return factory.createCreateTransformsInfoProfile( + createTransformsInfo, + supplements); + } + + /** + * Parse the <code>CreateTransformsInfo</code> DOM element contained in a + * <code>CreateTransformsInfoProfile</code>. + * + * @param profileElem The <code>CreateTransformsInfoProfile</code> DOM + * element containing the <code>CreateTransformsInfo</code>. + * @return The <code>CreateTransformsInfo</code> API object containinig the + * data from the <code>CreateTransformsInfo</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>CreateTransformsInfo</code> DOM element. + */ + private CreateTransformsInfo parseCreateTransformsInfo(Element profileElem) + throws MOAApplicationException { + + Element transformsElem = + (Element) XPathUtils.selectSingleNode( + profileElem, + CREATE_TRANSFORMS_XPATH); + Element metaInfoElem = + (Element) XPathUtils.selectSingleNode( + profileElem, + FINAL_DATA_META_INFO_XPATH); + MetaInfo finalDataMetaInfo; + List transforms; + + // parse the dsig:Transforms + if (transformsElem != null) { + TransformParser transformsParser = new TransformParser(); + transforms = transformsParser.parseTransforms(transformsElem); + } else { + transforms = null; + } + + // parse the meta info + finalDataMetaInfo = RequestParserUtils.parseMetaInfo(metaInfoElem); + + return factory.createCreateTransformsInfo(transforms, finalDataMetaInfo); + } + + /** + * Parse a <code>CreateSignatureEnvironmentProfile</code> DOM element. + * + * @param profileElem The <code>CreateSignatureEnvironmentProfile</code> + * DOM element to parse. + * @return The <code>CreateSignatureEnvironmentProfile</code> API object + * containing the data from the <code>profileElem</code>. + */ + public CreateSignatureEnvironmentProfile parseCreateSignatureEnvironmentProfile(Element profileElem) { + CreateSignatureLocation createSignatureLocation = + parseCreateSignatureLocation(profileElem); + List supplements = parseSupplements(profileElem); + + return factory.createCreateSignatureEnvironmentProfile( + createSignatureLocation, + supplements); + } + + /** + * Parse a <code>CreateSignatureLocation</code> DOM element contained in + * a <code>CreateSignatureEnvironmentProfile</code>. + * + * @param profileElem The <code>CreateSignatureEnvironmentProfile</code> DOM + * element containing the <code>CreateSignatureLocation</code>. + * @return The <code>CreateSignatureLocation</code> API object containing + * the data from the <code>CreateSignatureLocation</code> DOM element. + */ + private CreateSignatureLocation parseCreateSignatureLocation(Element profileElem) { + Element locationElem = + (Element) XPathUtils.selectSingleNode( + profileElem, + CREATE_SIGNATURE_LOCATION_XPATH); + String xPathExpression = DOMUtils.getText(locationElem); + Map namespaceDeclarations = DOMUtils.getNamespaceDeclarations(locationElem); + String indexStr = locationElem.getAttribute("Index"); + int index = Integer.parseInt(indexStr); + + return factory.createCreateSignatureLocation( + xPathExpression, + index, + namespaceDeclarations); + } + + /** + * Parse all <code>Supplement</code> DOM elements contained in a given + * parent DOM element. + * + * @param supplementsParentElem The DOM element being the parent of the + * <code>Supplement</code>s. + * @return A <code>List</code> of <code>Supplement</code> API objects + * containing the data from the <code>Supplement</code> DOM elements. + */ + private List parseSupplements(Element supplementsParentElem) { + List supplements = new ArrayList(); + NodeIterator supplementElems = + XPathUtils.selectNodeIterator(supplementsParentElem, SUPPLEMENT_XPATH); + Element supplementElem; + + while ((supplementElem = (Element) supplementElems.nextNode()) != null) { + XMLDataObjectAssociation supplement = + RequestParserUtils.parseXMLDataObjectAssociation(supplementElem); + supplements.add(supplement); + } + return supplements; + } + + /** + * Parse a <code>SupplementProfile</code> DOM element. + * + * @param profileElem The <code>SupplementProfile</code> DOM element to parse. + * @return The <code>SupplementProfile</code> API object containing the + * data from the <code>SupplementProfile</code> DOM element. + */ + public SupplementProfile parseSupplementProfile(Element profileElem) { + XMLDataObjectAssociation supplementProfile = + RequestParserUtils.parseXMLDataObjectAssociation(profileElem); + + return factory.createSupplementProfile(supplementProfile); + } + + /** + * Parse a <code>VerifyTransformsInfoProfile</code> DOM element. + * + * @param profileElem The <code>VerifyTransformsInfoProfile</code> DOM + * element to parse. + * @return A <code>VerifyTransformsInfoProfile</code> API object containing + * the information from the <code>VerifyTransformsInfoProfile</code> DOM + * element. + * @throws MOAApplicationException An error occurred parsing the + * <code>VerifyTransformsInfoProfile</code>. + */ + public VerifyTransformsInfoProfile parseVerifyTransformsInfoProfile(Element profileElem) + throws MOAApplicationException { + Element transformsElem = + (Element) XPathUtils.selectSingleNode( + profileElem, + VERIFY_TRANSFORMS_XPATH); + List transforms = null; + NodeIterator paramElems = + XPathUtils.selectNodeIterator(profileElem, TRANSFORM_PARAMETER_XPATH); + Element paramElem; + List transformParameters = new ArrayList(); + + // parse the dsig:Transforms + if (transformsElem != null) { + TransformParser transformsParser = new TransformParser(); + transforms = transformsParser.parseTransforms(transformsElem); + } + + // parse the TransformParameter elements + while ((paramElem = (Element) paramElems.nextNode()) != null) { + transformParameters.add(parseTransformParameter(paramElem)); + } + + return factory.createVerifyTransformsInfoProfile( + transforms, + transformParameters); + } + + /** + * Parse a <code>TransformParameter</code> DOM element. + * + * @param paramElem The <code>TransformParameter</code> DOM element to + * parse. + * @return The <code>TransformParameter</code> API object containing the + * information from the <code>TransformParameter</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>TransformParameter</code> DOM element. + */ + private TransformParameter parseTransformParameter(Element paramElem) + throws MOAApplicationException { + String uri = paramElem.getAttribute("URI"); + Element contentElem = + (Element) XPathUtils.selectSingleNode( + paramElem, + TRANSFORM_PARAMETER_CONTENT_XPATH); + + if (contentElem == null) { + return factory.createTransformParameter(uri); + } else if ("Base64Content".equals(contentElem.getLocalName())) { + String base64Str = DOMUtils.getText(contentElem); + InputStream binaryContent = Base64Utils.decodeToStream(base64Str, true); + + return factory.createTransformParameter(uri, binaryContent); + } else { // "Hash".equals(contentElem.getLocalName()) + String digestMethodStr = + XPathUtils.getElementValue(contentElem, DIGEST_METHOD_XPATH, ""); + String digestValueStr = + XPathUtils.getElementValue(contentElem, DIGEST_VALUE_XPATH, ""); + byte[] digestValue = null; + + try { + digestValue = Base64Utils.decode(digestValueStr, true); + } catch (IOException e) { + throw new MOAApplicationException("2270", null); + } + return factory.createTransformParameter( + uri, + digestMethodStr, + digestValue); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/RequestParserUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/RequestParserUtils.java new file mode 100644 index 000000000..0fff949b1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/RequestParserUtils.java @@ -0,0 +1,147 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.text.ParseException; +import java.util.Date; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.DateTimeUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; + +/** + * Utility methods for parsing XML requests definied in the MOA XML schema. + * + * @author Patrick Peck + * @version $Id$ + */ +public class RequestParserUtils { + // + // XPath expressions for parsing parts of a request + // + private static final String MOA = Constants.MOA_PREFIX + ":"; + private static final String REFERENCE_ATTR_NAME = "Reference"; + private static final String MIME_TYPE_XPATH = MOA + "MimeType"; + private static final String DESCRIPTION_XPATH = MOA + "Description"; + private static final String XML_ASSOC_CONTENT_XPATH = MOA + "Content"; + private static final String CONTENT_XPATH = + MOA + "Base64Content | " + MOA + "XMLContent"; + private static final String ANY_OTHER_XPATH = + "*[namespace-uri() != \"" + Constants.MOA_NS_URI + "\"]"; + + /** + * Parse a <code>XMLDataObjectAssociationType</code> kind of DOM element. + * + * @param assocElem The <code>XMLDataObjectAssociationType</code> kind of + * DOM elmeent to parse. + * @return The <code>XMLDataObjectAssociation</code> API object containing + * the data from the <code>XMLDataObjectAssociationType</code> DOM element. + */ + public static XMLDataObjectAssociation parseXMLDataObjectAssociation(Element assocElem) { + SPSSFactory factory = SPSSFactory.getInstance(); + MetaInfo metaInfo = parseMetaInfo(assocElem); + Element contentElem = + (Element) XPathUtils.selectSingleNode(assocElem, XML_ASSOC_CONTENT_XPATH); + Content content = parseContent(contentElem); + + return factory.createXMLDataObjectAssociation(metaInfo, content); + } + + /** + * Parse a <code>MetaInfoType</code> kind of DOM element. + * + * @param metaInfoElem The <code>MetaInfoType</code> kind of DOM element. + * @return The <code>MetaInfo</code> API object containing the data from + * the <code>metaInfoElem</code>. + */ + public static MetaInfo parseMetaInfo(Element metaInfoElem) { + SPSSFactory factory = SPSSFactory.getInstance(); + String mimeType = + XPathUtils.getElementValue(metaInfoElem, MIME_TYPE_XPATH, null); + String description = + XPathUtils.getElementValue(metaInfoElem, DESCRIPTION_XPATH, null); + NodeList anyOther = + XPathUtils.selectNodeList(metaInfoElem, ANY_OTHER_XPATH); + + return factory.createMetaInfo(mimeType, description, anyOther); + } + + /** + * Parse a <code>ContentOptionalRefType</code> or + * <code>ContentRequiredRefType</code> kind of DOM element. + * @param contentParentElem The DOM element being the parent of the + * content element. + * @return The <code>Content</code> API object containing the data from + * the given DOM element. + */ + public static Content parseContent(Element contentParentElem) { + SPSSFactory factory = SPSSFactory.getInstance(); + String referenceURI = + contentParentElem.hasAttribute(REFERENCE_ATTR_NAME) + ? contentParentElem.getAttribute(REFERENCE_ATTR_NAME) + : null; + Element contentElem = + (Element) XPathUtils.selectSingleNode(contentParentElem, CONTENT_XPATH); + + if (contentElem == null) { + return factory.createContent(referenceURI); + } + + if ("Base64Content".equals(contentElem.getLocalName())) { + String base64String = DOMUtils.getText(contentElem); + return factory.createContent( + Base64Utils.decodeToStream(base64String, true), + referenceURI); + } else { // "XMLContent".equals(contentElem.getLocalName()) + return factory.createContent(contentElem.getChildNodes(), referenceURI); + } + } + + /** + * Get the signing time from a Verfiy(CMS|XML)SignatureRequest. + * + * @param requestElem A <code>Verify(CMS|XML)SignatureRequest</code> DOM + * element. + * @param dateTimeXPath The XPath to lookup the <code>DateTime</code> element + * within the request. + * @return Date The date and time corresponding to the <code>DateTime</code> + * element in the request. If no <code>DateTime</code> element exists in the + * request, <code>null</code> is returned. + * @throws MOAApplicationException An error occurred during a parsing the + * <code>DateTime</code> element or creating the return value. + */ + public static Date parseDateTime(Element requestElem, String dateTimeXPath) + throws MOAApplicationException { + + Element dateTimeElem; + String dateTimeText; + + // select the DateTime element + dateTimeElem = + (Element) XPathUtils.selectSingleNode(requestElem, dateTimeXPath); + + // parse a date from the element value + if (dateTimeElem != null) { + dateTimeText = DOMUtils.getText(dateTimeElem); + try { + return DateTimeUtils.parseDateTime(dateTimeText); + } catch (ParseException e) { + throw new MOAApplicationException( + "1104", + new Object[] { dateTimeText }); + } + } else { + return null; + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ResponseBuilderUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ResponseBuilderUtils.java new file mode 100644 index 000000000..cc3e73e41 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ResponseBuilderUtils.java @@ -0,0 +1,213 @@ +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 <code>ResponseBuilder</code> 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 <code>SignerInfo</code> 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 <code>SignerInfo</code> element + * will be inserted. + * @param cert The signer certificate to add. + * @param isQualified Indicates, whether <code>cert</code> is a qualified + * certificate. + * @param isPublicAuthority Indicates, whether <code>cert</code> is + * certificate owned by a public authority. + * @param publicAuthorityID Information about the public authority owning + * <code>cert</code>. Must not be <code>null</code>, if + * <code>isPublicAuthority ! = null</code>. + * @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>Code</code> and <code>Info</code> + * 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>Code</code> subelement. + * @param info The content of the <code>Info</code> 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); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/TransformParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/TransformParser.java new file mode 100644 index 000000000..84f377826 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/TransformParser.java @@ -0,0 +1,251 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import org.w3c.dom.Element; +import org.w3c.dom.traversal.NodeIterator; + +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.Base64Transform; +import at.gv.egovernment.moa.spss.api.common.CanonicalizationTransform; +import at.gv.egovernment.moa.spss.api.common.EnvelopedSignatureTransform; +import at.gv.egovernment.moa.spss.api.common.ExclusiveCanonicalizationTransform; +import at.gv.egovernment.moa.spss.api.common.Transform; +import at.gv.egovernment.moa.spss.api.common.XPathFilter; +import at.gv.egovernment.moa.spss.api.common.XPathFilter2Transform; +import at.gv.egovernment.moa.spss.api.common.XPathTransform; +import at.gv.egovernment.moa.spss.api.common.XSLTTransform; + +/** + * A parser to parse XMLDsig <code>Transform</code> DOM elements into their + * MOA SPSS API representation. + * + * @author Patrick Peck + * @version $Id$ + */ +public class TransformParser { + // + // XPath expressions for selecting information from the DOM tree + // + private static final String DSIG = Constants.DSIG_PREFIX + ":"; + private static final String DSIG_FILTER2 = + Constants.DSIG_FILTER2_PREFIX + ":"; + private static final String XSLT = Constants.XSLT_PREFIX + ":"; + private static final String EC = Constants.DSIG_EC_PREFIX + ":"; + private static final String TRANSFORM_XPATH = DSIG + "Transform"; + private static final String XPATH_XPATH = DSIG + "XPath"; + private static final String XSLT_ELEMENT_XPATH = XSLT + "stylesheet"; + private static final String XPATH2_XPATH = + (DSIG_FILTER2 + "XPath[@Filter=\"intersect\"] | ") + + (DSIG_FILTER2 + "XPath[@Filter=\"subtract\"] | ") + + (DSIG_FILTER2 + "XPath[@Filter=\"union\"]"); + private static final String INCLUSIVE_NAMESPACES_XPATH = + EC + "InclusiveNamespaces"; + + /** + * The <code>SPSSFactory</code> to use for creating new API objects. + */ + private SPSSFactory factory = SPSSFactory.getInstance(); + + /** + * Parse an XMLDsig <code>Transforms</code> DOM element. + * + * @param transformsElem The <code>Transforms</code> DOM element to parse. + * @return A <code>List</code> of <code>Transform</code> API objects + * containing the data from the individual <code>Transform</code> DOM + * elements. + * @throws MOAApplicationException An error occurred parsing the + * <code>Transforms</code> DOM element. + */ + public List parseTransforms(Element transformsElem) + throws MOAApplicationException { + List transforms = new ArrayList(); + NodeIterator transformElems = + XPathUtils.selectNodeIterator(transformsElem, TRANSFORM_XPATH); + Element transformElem; + Transform transform; + + while ((transformElem = (Element) transformElems.nextNode()) != null) { + transform = parseTransform(transformElem); + transforms.add(transform); + } + + return transforms; + } + + /** + * Parse an XMLDsig <code>Transform</code> DOM element. + * + * @param transformElem <code>Transform</code> DOM element to parse. + * @return The <code>Transform</code> API object containing the data + * from the <code>Transform</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>Transform</code> DOM element. + */ + public Transform parseTransform(Element transformElem) + throws MOAApplicationException { + + String algorithmUri = transformElem.getAttribute("Algorithm"); + + if (CanonicalizationTransform.CANONICAL_XML.equals(algorithmUri) + || CanonicalizationTransform.CANONICAL_XML_WITH_COMMENTS.equals( + algorithmUri)) { + return factory.createCanonicalizationTransform(algorithmUri); + } else if ( + ExclusiveCanonicalizationTransform.EXCLUSIVE_CANONICAL_XML.equals( + algorithmUri) + || ExclusiveCanonicalizationTransform + .EXCLUSIVE_CANONICAL_XML_WITH_COMMENTS + .equals( + algorithmUri)) { + return parseExclusiveC14nTransform(algorithmUri, transformElem); + } else if (Base64Transform.BASE64_DECODING.equals(algorithmUri)) { + return factory.createBase64Transform(); + } else if ( + EnvelopedSignatureTransform.ENVELOPED_SIGNATURE.equals(algorithmUri)) { + return factory.createEnvelopedSignatureTransform(); + } else if (XPathTransform.XPATH.equals(algorithmUri)) { + return parseXPathTransform(transformElem); + } else if (XPathFilter2Transform.XPATH_FILTER2.equals(algorithmUri)) { + return parseXPathFilter2Transform(transformElem); + } else if (XSLTTransform.XSLT.equals(algorithmUri)) { + return parseXSLTTransform(transformElem); + } else { + throw new MOAApplicationException("1108", new Object[] { algorithmUri }); + } + } + + /** + * Parse an exclusive canonicalization type of transform. + * + * @param algorithmUri The algorithm URI of the canonicalization algorithm. + * @param transformElem The <code>Transform</code> DOM element to parse. + * @return An <code>ExclusiveCanonicalizationTransform</code> API object + * containing the data from the <code>transformElem</code>. + * @throws MOAApplicationException An error occurred parsing the + * <code>transformElem</code>. + */ + private Transform parseExclusiveC14nTransform( + String algorithmUri, + Element transformElem) + throws MOAApplicationException { + + Element inclusiveNamespacesElem = + (Element) XPathUtils.selectSingleNode( + transformElem, + INCLUSIVE_NAMESPACES_XPATH); + + if (inclusiveNamespacesElem == null) { + throw new MOAApplicationException("2217", null); + } else { + StringTokenizer tokenizer = + new StringTokenizer(inclusiveNamespacesElem.getAttribute("PrefixList")); + List inclusiveNamespaces = new ArrayList(); + + while (tokenizer.hasMoreTokens()) { + inclusiveNamespaces.add(tokenizer.nextToken()); + } + + return factory.createExclusiveCanonicalizationTransform( + algorithmUri, + inclusiveNamespaces); + } + } + + /** + * Parse an <code>XPath</code> type of <code>Transform</code>. + * + * @param transformElem The <code>Transform</code> DOM element to parse. + * @return The <code>Transform</code> API object representation of the + * <code>Transform</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>Transform</code> DOM element. + */ + private Transform parseXPathTransform(Element transformElem) + throws MOAApplicationException { + Element xPathElem = + (Element) XPathUtils.selectSingleNode(transformElem, XPATH_XPATH); + Map nsDecls; + + if (xPathElem == null) { + throw new MOAApplicationException("2202", null); + } + + nsDecls = DOMUtils.getNamespaceDeclarations(xPathElem); + nsDecls.remove(""); + + return factory.createXPathTransform(DOMUtils.getText(xPathElem), nsDecls); + } + + /** + * Parse an <code>XPathFilter2</code> type of <code>Transform</code>. + * + * @param transformElem The <code>Transform</code> DOM element to parse. + * @return The <code>Transform</code> API object representation of the + * <code>Transform</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>Transform</code> DOM element. + */ + private Transform parseXPathFilter2Transform(Element transformElem) + throws MOAApplicationException { + List filters = new ArrayList(); + NodeIterator iter = + XPathUtils.selectNodeIterator(transformElem, XPATH2_XPATH); + Element filterElem; + + while ((filterElem = (Element) iter.nextNode()) != null) { + String filterAttr = filterElem.getAttribute("Filter"); + String filterType; + String expression; + Map nsDecls; + + if (filterAttr.equals("intersect")) { + filterType = XPathFilter.INTERSECT_TYPE; + } else if (filterAttr.equals("subtract")) { + filterType = XPathFilter.SUBTRACT_TYPE; + } else { + filterType = XPathFilter.UNION_TYPE; + } + + expression = DOMUtils.getText(filterElem); + nsDecls = DOMUtils.getNamespaceDeclarations(filterElem); + nsDecls.remove(""); + filters.add(factory.createXPathFilter(filterType, expression, nsDecls)); + } + if (filters.size() == 0) { + throw new MOAApplicationException("2216", null); + } + + return factory.createXPathFilter2Transform(filters); + } + + /** + * Parse an <code>XSLT</code> type of <code>Transform</code>. + * + * @param transformElem The <code>Transform</code> DOM element to parse. + * @return The <code>Transform</code> API object representation of the + * <code>Transform</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>Transform</code> DOM element. + */ + private Transform parseXSLTTransform(Element transformElem) + throws MOAApplicationException { + Element xsltElem = + (Element) XPathUtils.selectSingleNode(transformElem, XSLT_ELEMENT_XPATH); + + if (xsltElem == null) { + throw new MOAApplicationException("2215", null); + } + + return factory.createXSLTTransform(xsltElem); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureRequestParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureRequestParser.java new file mode 100644 index 000000000..74d14b7cc --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureRequestParser.java @@ -0,0 +1,169 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.StringTokenizer; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.CollectionUtils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; + +/** + * A parser to parse <code>VerifyCMSSignatureRequest</code> DOM trees into + * <code>VerifyCMSSignatureRequest</code> API objects. + * + * @author Patrick Peck + * @version $Id$ + */ +public class VerifyCMSSignatureRequestParser { + + // + // XPath expressions for selecting parts of the DOM message + // + private static final String MOA = Constants.MOA_PREFIX + ":"; + private static final String DATE_TIME_XPATH = MOA + "DateTime"; + private static final String CMS_SIGNATURE_XPATH = MOA + "CMSSignature"; + private static final String TRUST_PROFILE_ID_XPATH = MOA + "TrustProfileID"; + private static final String DATA_OBJECT_XPATH = MOA + "DataObject"; + private static final String META_INFO_XPATH = MOA + "MetaInfo"; + private static final String CONTENT_XPATH = MOA + "Content"; + private static final String BASE64_CONTENT_XPATH = MOA + "Base64Content"; + + /** The <code>SPSSFactory</code> for creating new API objects. */ + private SPSSFactory factory = SPSSFactory.getInstance(); + + /** + * Parse a <code>VerifyCMSSignatureRequest</code> DOM element, as defined + * by the MOA schema. + * + * @param requestElem The <code>VerifyCMSSignatureRequest</code> to parse. The + * request must have been successfully parsed against the schema for this + * method to succeed. + * @return A <code>VerifyCMSSignatureRequest</code> API objects containing + * the data from the DOM element. + * @throws MOAApplicationException An error occurred parsing the request. + */ + public VerifyCMSSignatureRequest parse(Element requestElem) + throws MOAApplicationException { + + int[] signatories = parseSignatories(requestElem); + Date dateTime = + RequestParserUtils.parseDateTime(requestElem, DATE_TIME_XPATH); + String cmsSignatureStr = + XPathUtils.getElementValue(requestElem, CMS_SIGNATURE_XPATH, ""); + CMSDataObject dataObject = parseDataObject(requestElem); + String trustProfileID = + XPathUtils.getElementValue(requestElem, TRUST_PROFILE_ID_XPATH, null); + InputStream cmsSignature = + Base64Utils.decodeToStream(cmsSignatureStr, true); + + return factory.createVerifyCMSSignatureRequest( + signatories, + dateTime, + cmsSignature, + dataObject, + trustProfileID); + } + + /** + * Parse the <code>Signatories</code> attribute contained in the + * <code>VerifyCMSSignatureRequest</code> DOM element. + * + * @param requestElem The <code>VerifyCMSSignatureRequest</code> DOM element. + * @return The signatories contained in the given + * <code>VerifyCMSSignatureRequest</code> DOM element. + */ + private int[] parseSignatories(Element requestElem) { + String signatoriesStr = requestElem.getAttribute("Signatories"); + + if ("all".equals(signatoriesStr)) { + return VerifyCMSSignatureRequest.ALL_SIGNATORIES; + } else { + StringTokenizer tokenizer = new StringTokenizer(signatoriesStr); + List signatoriesList = new ArrayList(); + int[] signatories; + + // put the signatories into a List + while (tokenizer.hasMoreTokens()) { + try { + signatoriesList.add(new Integer(tokenizer.nextToken())); + } catch (NumberFormatException e) { + // this cannot occur if the request has been validated + } + } + + // convert the List into an int array + signatories = CollectionUtils.toIntArray(signatoriesList); + + return signatories; + } + } + + /** + * Parse a the <code>DataObject</code> DOM element contained in a given + * <code>VerifyCMSSignatureRequest</code> DOM element. + * + * @param requestElem The <code>VerifyCMSSignatureRequest</code> DOM element + * to parse. + * @return The <code>CMSDataObject</code> API object containing the data + * from the <code>DataObject</code> DOM element. + */ + private CMSDataObject parseDataObject(Element requestElem) { + Element dataObjectElem = + (Element) XPathUtils.selectSingleNode(requestElem, DATA_OBJECT_XPATH); + + if (dataObjectElem != null) { + Element metaInfoElem = + (Element) XPathUtils.selectSingleNode(dataObjectElem, META_INFO_XPATH); + MetaInfo metaInfo = null; + Element contentElem = + (Element) XPathUtils.selectSingleNode(dataObjectElem, CONTENT_XPATH); + CMSContent content = parseContent(contentElem); + + if (metaInfoElem != null) { + metaInfo = RequestParserUtils.parseMetaInfo(metaInfoElem); + } + + return factory.createCMSDataObject(metaInfo, content); + } else { + return null; + } + + } + + /** + * Parse the content contained in a <code>CMSContentBaseType</code> kind of + * DOM element. + * + * @param contentElem The <code>CMSContentBaseType</code> kind of element to + * parse. + * @return A <code>CMSDataObject</code> API object containing the data + * from the given DOM element. + */ + private CMSContent parseContent(Element contentElem) { + Element base64ContentElem = + (Element) XPathUtils.selectSingleNode(contentElem, BASE64_CONTENT_XPATH); + + if (base64ContentElem != null) { + String base64Str = DOMUtils.getText(base64ContentElem); + InputStream binaryContent = Base64Utils.decodeToStream(base64Str, true); + return factory.createCMSContent(binaryContent); + } else { + return factory.createCMSContent( + contentElem.getAttribute("Reference")); + } + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureResponseBuilder.java new file mode 100644 index 000000000..3fc8f223d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureResponseBuilder.java @@ -0,0 +1,101 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.util.Iterator; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; + +/** + * Convert a <code>VerifyCMSSignatureResponse</code> API object into its + * XML representation, according to the MOA XML schema. + * + * @author Patrick Peck + * @version $Id$ + */ +public class VerifyCMSSignatureResponseBuilder { + /** The XML document containing the response element. */ + private Document responseDoc; + /** The response <code>VerifyCMSSignatureResponse</code> DOM element. */ + private Element responseElem; + + /** + * Create a new <code>VerifyCMSSignatureResponseBuilder</code>: + * + * @throws MOASystemException An error occurred setting up the resulting + * XML document. + */ + public VerifyCMSSignatureResponseBuilder() throws MOASystemException { + responseDoc = + ResponseBuilderUtils.createResponse("VerifyCMSSignatureResponse"); + responseElem = responseDoc.getDocumentElement(); + } + + /** + * Build a document containing a <code>VerifyCMSSignatureResponse</code> + * DOM element being the XML representation of the given + * <code>VerifyCMSSignatureResponse</code> API object. + * + * @param response The <code>VerifyCMSSignatureResponse</code> to convert + * to XML. + * @return A document containing the <code>VerifyCMSSignatureResponse</code> + * DOM element. + * @throws MOAApplicationException An error occurred building the response. + */ + public Document build(VerifyCMSSignatureResponse response) + throws MOAApplicationException { + + Iterator iter; + + for (iter = response.getResponseElements().iterator(); iter.hasNext();) { + VerifyCMSSignatureResponseElement responseElement = + (VerifyCMSSignatureResponseElement) iter.next(); + addResponseElement(responseElement); + } + + return responseDoc; + } + + /** + * Add an element to the response. + * + * @param responseElement The element to add to the response. + * @throws MOAApplicationException An error occurred adding the element. + */ + private void addResponseElement(VerifyCMSSignatureResponseElement responseElement) + throws MOAApplicationException { + + SignerInfo signerInfo = responseElement.getSignerInfo(); + CheckResult signatureCheck = responseElement.getSignatureCheck(); + CheckResult certCheck = responseElement.getCertificateCheck(); + + ResponseBuilderUtils.addSignerInfo( + responseDoc, + responseElem, + signerInfo.getSignerCertificate(), + signerInfo.isQualifiedCertificate(), + signerInfo.isPublicAuthority(), + signerInfo.getPublicAuhtorityID()); + + ResponseBuilderUtils.addCodeInfoElement( + responseDoc, + responseElem, + "SignatureCheck", + signatureCheck.getCode(), + signatureCheck.getInfo()); + + ResponseBuilderUtils.addCodeInfoElement( + responseDoc, + responseElem, + "CertificateCheck", + certCheck.getCode(), + certCheck.getInfo()); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureRequestParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureRequestParser.java new file mode 100644 index 000000000..e736af522 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureRequestParser.java @@ -0,0 +1,275 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.traversal.NodeIterator; + +import at.gv.egovernment.moa.util.BoolUtils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; + +/** + * @author Patrick Peck + * @version $Id$ + */ +public class VerifyXMLSignatureRequestParser { + + // + // XPath expressions for parsing parts of the request + // + private static final String MOA = Constants.MOA_PREFIX + ":"; + private static final String DATE_TIME_XPATH = MOA + "DateTime"; + private static final String RETURN_HASH_INPUT_DATA_XPATH = + MOA + "ReturnHashInputData"; + private static final String TRUST_PROFILE_ID_XPATH = MOA + "TrustProfileID"; + private static final String VERIFY_SIGNATURE_ENVIRONMENT_XPATH = + MOA + "VerifySignatureInfo/" + MOA + "VerifySignatureEnvironment"; + private static final String VERIFY_SIGNATURE_LOCATION_XPATH = + MOA + "VerifySignatureInfo/" + MOA + "VerifySignatureLocation"; + private static final String SUPPLEMENT_PROFILE_XPATH = + MOA + "SupplementProfile | " + MOA + "SupplementProfileID"; + private static final String SIGNATURE_MANIFEST_CHECK_PARAMS_XPATH = + MOA + "SignatureManifestCheckParams"; + private static final String VERIFY_TRANSFORMS_INFO_PROFILE_XPATH = + (MOA + "VerifyTransformsInfoProfile | ") + + (MOA + "VerifyTransformsInfoProfileID"); + private static final String REFERENCE_INFO_XPATH = MOA + "ReferenceInfo"; + + /** The <code>SPSSFactory</code> for creating new API objects. */ + private SPSSFactory factory = SPSSFactory.getInstance(); + + + /** + * Parse a <code>VerifyXMLSignatureRequest</code> DOM element, as defined + * by the MOA schema. + * + * @param requestElem The <code>VerifyXMLSignatureRequest</code> to parse. The + * request must have been successfully parsed against the schema for this + * method to succeed. + * @return A <code>VerifyXMLSignatureRequest</code> API object containing + * the data from the DOM element. + * @throws MOAApplicationException An error occurred parsing the request. + */ + public VerifyXMLSignatureRequest parse(Element requestElem) + throws MOAApplicationException { + + Date dateTime = + RequestParserUtils.parseDateTime(requestElem, DATE_TIME_XPATH); + VerifySignatureInfo verifySignatureInfo = + parseVerifySignatureInfo(requestElem); + List supplementProfiles = parseSupplementProfiles(requestElem); + SignatureManifestCheckParams signatureManifestCheckParams = + parseSignatureManifestCheckParams(requestElem); + boolean returnHashInputData = + XPathUtils.selectSingleNode(requestElem, RETURN_HASH_INPUT_DATA_XPATH) + != null; + String trustProfileID = + XPathUtils.getElementValue(requestElem, TRUST_PROFILE_ID_XPATH, null); + + return factory.createVerifyXMLSignatureRequest( + dateTime, + verifySignatureInfo, + supplementProfiles, + signatureManifestCheckParams, + returnHashInputData, + trustProfileID); + } + + /** + * Parse the <code>VerifySignatureInfo</code> DOM element contained in + * the <code>VerifyXMLSignatureRequest</code> DOM element. + * + * @param requestElem The <code>VerifyXMLSignatureRequest</code> DOM element + * containing the <code>VerifySignatureInfo</code> DOM element. + * @return The <code>VerifySignatureInfo</code> API object containing the + * data from the DOM element. + */ + private VerifySignatureInfo parseVerifySignatureInfo(Element requestElem) { + Element verifySignatureEnvironmentElem = + (Element) XPathUtils.selectSingleNode( + requestElem, + VERIFY_SIGNATURE_ENVIRONMENT_XPATH); + Content verifySignatureEnvironment = + RequestParserUtils.parseContent(verifySignatureEnvironmentElem); + VerifySignatureLocation verifySignatureLocation = + parseVerifySignatureLocation(requestElem); + + return factory.createVerifySignatureInfo( + verifySignatureEnvironment, + verifySignatureLocation); + } + + /** + * Parse the <code>VerifySignatureLocation</code> DOM element contained + * in the given <code>VerifyXMLSignatureRequest</code> DOM element. + * + * @param requestElem The <code>VerifyXMLSignatureRequst</code> DOM element. + * @return The <code>VerifySignatureLocation</code> API object containing the + * data from the DOM element. + */ + private VerifySignatureLocation parseVerifySignatureLocation(Element requestElem) { + Element locationElem = + (Element) XPathUtils.selectSingleNode( + requestElem, + VERIFY_SIGNATURE_LOCATION_XPATH); + String xPathExpression = DOMUtils.getText(locationElem); + Map namespaceDeclarations = DOMUtils.getNamespaceDeclarations(locationElem); + + return factory.createVerifySignatureLocation( + xPathExpression, + namespaceDeclarations); + } + + /** + * Parse the supplement profiles contained in the given + * <code>VerifyXMLSignatureRequest</code> DOM element. + * + * @param requestElem The <code>VerifyXMLSignatureRequest</code> DOM element. + * @return A <code>List</code> of <code>SupplementProfile</code> API objects + * containing the data from the <code>SupplementProfile</code> DOM elements. + */ + private List parseSupplementProfiles(Element requestElem) { + List supplementProfiles = new ArrayList(); + NodeIterator profileElems = + XPathUtils.selectNodeIterator(requestElem, SUPPLEMENT_PROFILE_XPATH); + Element profileElem; + + while ((profileElem = (Element) profileElems.nextNode()) != null) { + SupplementProfile profile; + + if ("SupplementProfile".equals(profileElem.getLocalName())) { + ProfileParser profileParser = new ProfileParser(); + profile = profileParser.parseSupplementProfile(profileElem); + } else { + String profileID = DOMUtils.getText(profileElem); + profile = factory.createSupplementProfile(profileID); + } + supplementProfiles.add(profile); + } + return supplementProfiles; + } + + /** + * Parse the <code>SignatureManifestCheckParams</code> DOM element contained + * in the given <code>VerifyXMLSignatureRequest</code> DOM element. + * @param requestElem The <code>VerifyXMLSignatureRequest</code> DOM element. + * @return The <code>SignatureManifestCheckParams</code> API object containing + * the data from the <code>SignatureManifestCheckParams</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>SignatureManifestCheckParams</code> DOM element. + */ + private SignatureManifestCheckParams parseSignatureManifestCheckParams(Element requestElem) + throws MOAApplicationException { + Element paramsElem = + (Element) XPathUtils.selectSingleNode( + requestElem, + SIGNATURE_MANIFEST_CHECK_PARAMS_XPATH); + + if (paramsElem != null) { + String returnReferenceInputDataStr = + paramsElem.getAttribute("ReturnReferenceInputData"); + boolean returnReferencInputData = + BoolUtils.valueOf(returnReferenceInputDataStr); + List referenceInfos = parseReferenceInfos(paramsElem); + + return factory.createSignatureManifestCheckParams( + referenceInfos, + returnReferencInputData); + } else { + return null; + } + } + + /** + * Parse the <code>ReferenceInfo</code> DOM elements contained in a + * <code>SignatureManifestCheckParams</code> DOM element. + * + * @param paramsElem The <code>SignatureManifestCheckParams</code> DOM element + * containing the <code>ReferenceInfo</code> DOM elements. + * @return A <code>List</code> of <code>RefernceInfo</code> API objects + * containing the data from the <code>ReferenceInfo</code> DOM elements. + * @throws MOAApplicationException An error occurred parsing the + * <code>ReferenceInfo</code> DOM elements. + */ + private List parseReferenceInfos(Element paramsElem) + throws MOAApplicationException { + + List referenceInfos = new ArrayList(); + NodeIterator refInfoElems = + XPathUtils.selectNodeIterator(paramsElem, REFERENCE_INFO_XPATH); + Element refInfoElem; + + while ((refInfoElem = (Element) refInfoElems.nextNode()) != null) { + ReferenceInfo referenceInfo = parseReferenceInfo(refInfoElem); + + referenceInfos.add(referenceInfo); + } + + return referenceInfos; + } + + /** + * Parse a <code>ReferenceInfo</code> DOM element. + * + * @param refInfoElem The <code>ReferenceInfo</code> DOM element to parse. + * @return The <code>ReferenceInfo</code> API object containing the data + * from the given <code>ReferenceInfo</code> DOM element. + * @throws MOAApplicationException An error occurred parsing the + * <code>ReferenceInfo</code> DOM element. + */ + private ReferenceInfo parseReferenceInfo(Element refInfoElem) + throws MOAApplicationException { + List profiles = parseVerifyTransformsInfoProfiles(refInfoElem); + return factory.createReferenceInfo(profiles); + } + + /** + * Parse the <code>VerifyTransformsInfoProfile</code> DOM elements contained + * in a <code>ReferenceInfo</code> DOM element. + * + * @param refInfoElem <code>ReferenceInfo</code> DOM element containing + * the <code>VerifyTransformsInfoProfile</code> DOM elements. + * @return A <code>List</code> of <code>VerifyTransformsInfoProfile</code> + * API objects containing the profile data. + * @throws MOAApplicationException An error occurred building the + * <code>VerifyTransformsInfoProfile</code>s. + */ + private List parseVerifyTransformsInfoProfiles(Element refInfoElem) + throws MOAApplicationException { + + List profiles = new ArrayList(); + NodeIterator profileElems = + XPathUtils.selectNodeIterator( + refInfoElem, + VERIFY_TRANSFORMS_INFO_PROFILE_XPATH); + Element profileElem; + + while ((profileElem = (Element) profileElems.nextNode()) != null) { + if ("VerifyTransformsInfoProfile".equals(profileElem.getLocalName())) { + ProfileParser profileParser = new ProfileParser(); + profiles.add( + profileParser.parseVerifyTransformsInfoProfile(profileElem)); + } else { + String profileID = DOMUtils.getText(profileElem); + profiles.add(factory.createVerifyTransformsInfoProfile(profileID)); + } + } + return profiles; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureResponseBuilder.java new file mode 100644 index 000000000..56bcf63fa --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureResponseBuilder.java @@ -0,0 +1,300 @@ +package at.gv.egovernment.moa.spss.api.xmlbind; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +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; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.ContentBinary; +import at.gv.egovernment.moa.spss.api.common.ContentXML; +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; + +/** + * Convert a <code>VerifyXMLSignatureResponse</code> API object into its + * XML representation, according to the MOA XML schema. + * + * @author Patrick Peck + * @version $Id$ + */ +public class VerifyXMLSignatureResponseBuilder { + private static final String MOA_NS_URI = Constants.MOA_NS_URI; + + /** The XML document containing the response element. */ + private Document responseDoc; + /** The response <code>VerifyXMLSignatureResponse</code> DOM element. */ + private Element responseElem; + + /** + * Create a new <code>VerifyXMLSignatureResponseBuilder</code>: + * + * @throws MOASystemException An error occurred setting up the resulting + * XML document. + */ + public VerifyXMLSignatureResponseBuilder() throws MOASystemException { + responseDoc = + ResponseBuilderUtils.createResponse("VerifyXMLSignatureResponse"); + responseElem = responseDoc.getDocumentElement(); + } + + /** + * Build a document containing a <code>VerifyXMLSignatureResponse</code> + * DOM element being the XML representation of the given + * <code>VerifyXMLSignatureResponse</code> API object. + * + * @param response The <code>VerifyXMLSignatureResponse</code> to convert + * to XML. + * @return A document containing the <code>VerifyXMLSignatureResponse</code> + * DOM element. + * @throws MOAApplicationException An error occurred building the response. + */ + public Document build(VerifyXMLSignatureResponse response) + throws MOAApplicationException { + + Iterator iter; + List responseData; + + // add the SignerInfo + ResponseBuilderUtils.addSignerInfo( + responseDoc, + responseElem, + response.getSignerInfo().getSignerCertificate(), + response.getSignerInfo().isQualifiedCertificate(), + response.getSignerInfo().isPublicAuthority(), + response.getSignerInfo().getPublicAuhtorityID()); + + // add HashInputData elements + responseData = response.getHashInputDatas(); + if (responseData != null && !responseData.isEmpty()) { + for (iter = responseData.iterator(); iter.hasNext();) { + Content content = (Content) iter.next(); + addContent("HashInputData", content); + } + } + + // add ReferenceInputData elements + responseData = response.getReferenceInputDatas(); + if (responseData != null && !responseData.isEmpty()) { + for (iter = responseData.iterator(); iter.hasNext();) { + Content content = (Content) iter.next(); + addContent("ReferenceInputData", content); + } + } + + // add the SignatureCheck + addReferencesCheckResult("SignatureCheck", response.getSignatureCheck()); + + // add the SignatureManifestCheck + if (response.getSignatureManifestCheck() != null) { + addReferencesCheckResult( + "SignatureManifestCheck", + response.getSignatureManifestCheck()); + } + + // add the XMLDsigManifestChecks + responseData = response.getXMLDsigManifestChecks(); + if (responseData != null && !responseData.isEmpty()) { + for (iter = responseData.iterator(); iter.hasNext();) { + ManifestRefsCheckResult checkResult = + (ManifestRefsCheckResult) iter.next(); + addManifestRefsCheckResult("XMLDSIGManifestCheck", checkResult); + } + } + + // add the CertificateCheck + ResponseBuilderUtils.addCodeInfoElement( + responseDoc, + responseElem, + "CertificateCheck", + response.getCertificateCheck().getCode(), + response.getCertificateCheck().getInfo()); + + return responseDoc; + } + + /** + * Add an element of type <code>ContentBaseType</code> to the response. + * + * @param elementName The name of the element. + * @param content The <code>Content</code> to add. Based on the type of + * the <code>Content</code>, either a <code>Base64Content</code> element + * or a <code>XMLContent</code> subelement will be added. A + * <code>ContentBinary</code> of type <code>BinaryDataObject</code> will be + * added as a <code>Base64Content</code> child element. + * <code>ContentXML</code> will be added as <code>XMLContent</code> child + * element. + * @throws MOAApplicationException An error occurred adding the content. + */ + private void addContent(String elementName, Content content) + throws MOAApplicationException { + + Element contentElem = responseDoc.createElementNS(MOA_NS_URI, elementName); + + switch (content.getContentType()) { + case Content.XML_CONTENT : + ContentXML contentXml = (ContentXML) content; + NodeList nodes = contentXml.getXMLContent(); + Element xmlElem; + int i; + + xmlElem = responseDoc.createElementNS(MOA_NS_URI, "XMLContent"); + //xmlElem.setAttributeNS(XML_NS_URI, "xml:space", "preserve"); + xmlElem.setAttribute("xml:space", "preserve"); + + for (i = 0; i < nodes.getLength(); i++) { + xmlElem.appendChild(responseDoc.importNode(nodes.item(i), true)); + } + contentElem.appendChild(xmlElem); + responseElem.appendChild(contentElem); + break; + case Content.BINARY_CONTENT : + Element binaryElem = + responseDoc.createElementNS(MOA_NS_URI, "Base64Content"); + ContentBinary contentBinary = (ContentBinary) content; + String base64Str; + + try { + base64Str = Base64Utils.encode(contentBinary.getBinaryContent()); + } catch (IOException e) { + throw new MOAApplicationException("2200", null, e); + } + binaryElem.appendChild(responseDoc.createTextNode(base64Str)); + contentElem.appendChild(binaryElem); + responseElem.appendChild(contentElem); + break; + } + } + + /** + * Add a <code>ReferencesCheckResult</code> to the response. + * + * @param elementName The DOM element name to use. + * @param checkResult The <code>ReferencesCheckResult</code> to add. + */ + private void addReferencesCheckResult( + String elementName, + ReferencesCheckResult checkResult) { + + NodeList info = null; + + if (checkResult.getInfo() != null) { + DocumentFragment fragment = responseDoc.createDocumentFragment(); + NodeList anyOtherInfo = checkResult.getInfo().getAnyOtherInfo(); + int[] failedReferences = checkResult.getInfo().getFailedReferences(); + + if (anyOtherInfo != null) { + addAnyOtherInfo(fragment, checkResult.getInfo().getAnyOtherInfo()); + } + + if (failedReferences != null) { + addFailedReferences(fragment, failedReferences); + } + + info = fragment.getChildNodes(); + } + + ResponseBuilderUtils.addCodeInfoElement( + responseDoc, + responseElem, + elementName, + checkResult.getCode(), + info); + } + + + /** + * Add a <code>ManifestRefsCheckResult</code> to the response. + * + * @param elementName The DOM element name to use. + * @param checkResult The <code>ManifestRefsCheckResult</code> to add. + */ + private void addManifestRefsCheckResult( + String elementName, + ManifestRefsCheckResult checkResult) { + + DocumentFragment fragment = responseDoc.createDocumentFragment(); + NodeList anyOtherInfo = checkResult.getInfo().getAnyOtherInfo(); + int[] failedReferences = checkResult.getInfo().getFailedReferences(); + Element referringSigRefElem; + String referringSigRefStr; + + // add any other elements + if (anyOtherInfo != null) { + addAnyOtherInfo(fragment, checkResult.getInfo().getAnyOtherInfo()); + } + + // add the failed references + if (failedReferences != null) { + addFailedReferences(fragment, failedReferences); + } + + // add the ReferringSigReference + referringSigRefElem = + responseDoc.createElementNS(MOA_NS_URI, "ReferringSigReference"); + referringSigRefStr = + Integer.toString(checkResult.getInfo().getReferringSignatureReference()); + referringSigRefElem.appendChild( + responseDoc.createTextNode(referringSigRefStr)); + fragment.appendChild(referringSigRefElem); + + // add XMLDSIGManifestCheckResult to the response + ResponseBuilderUtils.addCodeInfoElement( + responseDoc, + responseElem, + elementName, + checkResult.getCode(), + fragment.getChildNodes()); + } + + /** + * Add arbitrary XML content to a DOM <code>DocumentFragment</code>. + * + * @param fragment The fragment to add the XML content to. + * @param anyOtherInfo The XML content to add. + */ + private void addAnyOtherInfo( + DocumentFragment fragment, + NodeList anyOtherInfo) { + + int i; + + for (i = 0; i < anyOtherInfo.getLength(); i++) { + fragment.appendChild(responseDoc.importNode(anyOtherInfo.item(i), true)); + } + } + + /** + * Add the failed references as <code>FailedReference</code> DOM elements to + * the fragment. + * + * @param fragment The DOM document fragment to add the + * <code>FailedReference</code> elements to. + * @param failedReferences The indexes of the failed references. + */ + private void addFailedReferences( + DocumentFragment fragment, + int[] failedReferences) { + Element failedReferenceElem; + int i; + + for (i = 0; i < failedReferences.length; i++) { + failedReferenceElem = + responseDoc.createElementNS(MOA_NS_URI, "FailedReference"); + failedReferenceElem.appendChild( + responseDoc.createTextNode(Integer.toString(failedReferences[i]))); + fragment.appendChild(failedReferenceElem); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfile.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfile.java new file mode 100644 index 000000000..425c410ad --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfile.java @@ -0,0 +1,30 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +/** + * Base class for signature environment profile data used in XML signature + * creation. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface CreateSignatureEnvironmentProfile { + /** + * Indicates that the profile data is given explicitly. + */ + public static int EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE = 0; + /** + * Indicates that the profile data is stored in the configuration and resolved + * using an ID. + */ + public static int ID_CREATESIGNATUREENVIRONMENTPROFILE = 1; + + /** + * Gets the type of this object. + * + * @return The type of <code>CreateSignatureEnvironmentProfile</code> denoted + * by this object. Either + * <code>EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE</code> or + * <code>ID_CREATESIGNATUREENVIRONMENTPROFILE</code>. + */ + public int getCreateSignatureEnvironmentProfileType(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfileExplicit.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfileExplicit.java new file mode 100644 index 000000000..6aebd102b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfileExplicit.java @@ -0,0 +1,30 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import java.util.List; + +/** + * A <code>CreateSignatureEnvironmentProfile</code> containing the profile + * data explicitly. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface CreateSignatureEnvironmentProfileExplicit + extends CreateSignatureEnvironmentProfile { + + /** + * Gets the location and index of where to insert the signature into the + * signature environment. + * + * @return The location and index of the signature in the signature + * environment. + */ + public CreateSignatureLocation getCreateSignatureLocation(); + /** + * Gets the supplemental information. + * + * @return The supplemental information. + */ + public List getSupplements(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfileID.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfileID.java new file mode 100644 index 000000000..1c0d87adc --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureEnvironmentProfileID.java @@ -0,0 +1,20 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +/** + * A <code>CreateSignatureEnvironmentProfile</code> containing a profile ID + * pointing to locally stored profile data. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface CreateSignatureEnvironmentProfileID + extends CreateSignatureEnvironmentProfile { + + /** + * Gets the profile ID. + * + * @return The profile ID. + */ + public String getCreateSignatureEnvironmentProfileID(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureInfo.java new file mode 100644 index 000000000..5ceae4d0a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureInfo.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import at.gv.egovernment.moa.spss.api.common.Content; + +/** + * Encapsulates a signature object used during signature creation. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateSignatureInfo { + /** + * Gets the XML structure where the signature will be inserted. + * + * @return The XML structure where the signature will be inserted. + */ + public Content getCreateSignatureEnvironment(); + /** + * Gets the supplemental data for the signature environment. + * + * @return The supplemental data for the signature envoronment. + */ + public CreateSignatureEnvironmentProfile getCreateSignatureEnvironmentProfile(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureLocation.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureLocation.java new file mode 100644 index 000000000..81374ceaa --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateSignatureLocation.java @@ -0,0 +1,23 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import at.gv.egovernment.moa.spss.api.common.ElementSelector; + +/** + * Specifies where to insert the newly created signature. + * + * An XPath expression is used to select the signature parent element. An + * additional index specifies the node index after which to insert the + * signature into the parent element. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface CreateSignatureLocation extends ElementSelector { + /** + * Gets the node index, after which the signature will be inserted into the + * parent elemen. + * + * @return The index of the node after which the signature will be inserted. + */ + public int getIndex(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfo.java new file mode 100644 index 000000000..94152434e --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfo.java @@ -0,0 +1,27 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import java.util.List; + +import at.gv.egovernment.moa.spss.api.common.MetaInfo; + +/** + * Encapsulates information used for the transformation of the data object. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateTransformsInfo { + /** + * Gets the XMLDSig transforms. + * + * @return A <code>List</code> of <code>Transform</code> objects. + */ + public List getTransforms(); + /** + * Gets meta information about the data resulting from the transformation. + * + * @return Meta information about the resulting data. + */ + public MetaInfo getFinalDataMetaInfo(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfile.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfile.java new file mode 100644 index 000000000..40acfd317 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfile.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +/** + * Base class for transformation informations used in signature creation. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateTransformsInfoProfile { + /** + * Indicates transformation information given explicitly. + */ + public static final int EXPLICIT_CREATETRANSFORMSINFOPROFILE = 0; + /** + * Indicates transformation information given as an ID. + */ + public static final int ID_CREATETRANSFORMSINFOPROFILE = 1; + + /** + * Gets the type of profile information this object contains. + * + * @return The type of transformation information, either + * <code>EXPLICIT_CREATETRANSFORMSINFOPROFILE</code> or + * <code>ID_CREATETRANSFORMSINFOPROFILE</code>. + */ + public int getCreateTransformsInfoProfileType(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfileExplicit.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfileExplicit.java new file mode 100644 index 000000000..aeb74445f --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfileExplicit.java @@ -0,0 +1,26 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import java.util.List; + +/** + * Encapsulates explicit transformation informations. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateTransformsInfoProfileExplicit + extends CreateTransformsInfoProfile { + /** + * Gets the transformation information of the data object. + * + * @return Transformation information of the data object. + */ + public CreateTransformsInfo getCreateTransformsInfo(); + /** + * Gets the supplemental information. + * + * @return The supplemental information. + */ + public List getSupplements(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfileID.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfileID.java new file mode 100644 index 000000000..3631ead29 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateTransformsInfoProfileID.java @@ -0,0 +1,18 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +/** + * Encapsulates transformation information given via an identifier. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateTransformsInfoProfileID + extends CreateTransformsInfoProfile { + /** + * Gets the ID of the transformation. + * + * @return The transformation profile ID. + */ + public String getCreateTransformsInfoProfileID(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureRequest.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureRequest.java new file mode 100644 index 000000000..b8157fdfb --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureRequest.java @@ -0,0 +1,26 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import java.util.List; + + +/** + * Object that encapsulates a request to create an XML Signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateXMLSignatureRequest { + /** + * Gets the identifier for the keys to be used for the signature. + * + * @return The identifier for the keys to be used. + */ + public String getKeyIdentifier(); + /** + * Gets the information of the singleSignatureInfo elements. + * + * @return The information of singleSignatureInfo elements. + */ + public List getSingleSignatureInfos(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureResponse.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureResponse.java new file mode 100644 index 000000000..6bf54e6a5 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureResponse.java @@ -0,0 +1,20 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import java.util.List; + +/** + * Object that encapsulates the response on to a + * <code>CreateXMLSignatureRequest</code> to create an XML signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateXMLSignatureResponse { + /** + * Gets the response elements. + * + * @return The response elements. + */ + public List getResponseElements(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureResponseElement.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureResponseElement.java new file mode 100644 index 000000000..2162d82fd --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/CreateXMLSignatureResponseElement.java @@ -0,0 +1,29 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +/** + * Base class for <code>SignatureEnvironmentResponse</code> and + * <code>ErrorResponse</code> elements in a + * <code>CreateXMLSignatureResponse</code>. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface CreateXMLSignatureResponseElement { + /** + * Indicates that this object contains a <code>SignatureEnvironment</code>. + */ + public static final int SIGNATURE_ENVIRONMENT_RESPONSE = 0; + /** + * Indicates that this objet contains an <code>ErrorResponse</code>. + */ + public static final int ERROR_RESPONSE = 1; + + /** + * Gets the type of response object. + * + * @return The type of response object, either + * <code>SIGNATURE_ENVIRONMENT_RESPONSE</code> or <code>ERROR_RESPONSE</code>. + */ + public int getResponseType(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/DataObjectInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/DataObjectInfo.java new file mode 100644 index 000000000..43d49c587 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/DataObjectInfo.java @@ -0,0 +1,48 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import at.gv.egovernment.moa.spss.api.common.Content; + +/** + * Encapsulates information required to create a single signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface DataObjectInfo { + /** + * Indicates that a detached signature will be created. + */ + public static final String STRUCTURE_DETACHED = "detached"; + /** + * Indicates that an enveloping signature will be created. + */ + public static final String STRUCTURE_ENVELOPING = "enveloping"; + + /** + * Gets the structure of the signature. + * + * @return The structure of the signature. + */ + public String getStructure(); + /** + * Checks whether a refercence will be placed in the signature itself or + * in the manifest. + * + * @return <code>true</code> if a reference will be placed in the manifest, + * <code>false</code> if it will be placed in the signature. + */ + public boolean isChildOfManifest(); + /** + * Gets information related to a single data object. + * + * @return Information related to a single data object. + */ + public Content getDataObject(); + /** + * Gets information for the transformation of the data object. + * + * @return The transformation information. + */ + public CreateTransformsInfoProfile getCreateTransformsInfoProfile(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/ErrorResponse.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/ErrorResponse.java new file mode 100644 index 000000000..30fa4fb52 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/ErrorResponse.java @@ -0,0 +1,24 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + + +/** + * Object containing detailed error information. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface ErrorResponse extends CreateXMLSignatureResponseElement { + /** + * Gets the error code. + * + * @return The error code. + */ + public int getErrorCode(); + /** + * Gets verbose error information. + * + * @return Verbose error information. + */ + public String getInfo(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/SignatureEnvironmentResponse.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/SignatureEnvironmentResponse.java new file mode 100644 index 000000000..449349a68 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/SignatureEnvironmentResponse.java @@ -0,0 +1,20 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import org.w3c.dom.Element; + +/** + * Contains the signature if the signature creation was successful. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface SignatureEnvironmentResponse + extends CreateXMLSignatureResponseElement { + /** + * Gets the XML structure which contains the signature. + * + * @return A general XML structure containing the signature. + */ + public Element getSignatureEnvironment(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/SingleSignatureInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/SingleSignatureInfo.java new file mode 100644 index 000000000..9c74c5157 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlsign/SingleSignatureInfo.java @@ -0,0 +1,32 @@ +package at.gv.egovernment.moa.spss.api.xmlsign; + +import java.util.List; + +/** + * Encapsulates data to create a single signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface SingleSignatureInfo { + /** + * Gets the dataObjectInfo information. + * + * @return The dataObjectInfo information. + */ + public List getDataObjectInfos(); + /** + * Gets the signature object. + * + * @return The signature object used during signature creation. + */ + public CreateSignatureInfo getCreateSignatureInfo(); + /** + * Check whether a Security Layer conform signature manifest will be created. + * + * @return <code>true</code>, if a Security Layer conform signature manifest + * will be created, <code>false</code> otherwise. + */ + public boolean isSecurityLayerConform(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ManifestRefsCheckResult.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ManifestRefsCheckResult.java new file mode 100644 index 000000000..1984ba349 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ManifestRefsCheckResult.java @@ -0,0 +1,24 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + + +/** + * Contains the results of manifest checks according to XMLDsig. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface ManifestRefsCheckResult { + /** + * Gets the check code. + * + * @return A numerical representation of the result of the manifest check. + */ + public int getCode(); + /** + * Gets the reference to the manifest. + * + * @return The reference to the manifest. + */ + public ManifestRefsCheckResultInfo getInfo(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ManifestRefsCheckResultInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ManifestRefsCheckResultInfo.java new file mode 100644 index 000000000..258840162 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ManifestRefsCheckResultInfo.java @@ -0,0 +1,19 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + + +/** + * Encapsulates information referring to the manifest of the check. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface ManifestRefsCheckResultInfo extends ReferencesCheckResultInfo { + /** + * Gets the position of the signature reference containing the + * reference to the manifest being described by this object. + * + * @return The position of the signature reference. + */ + public int getReferringSignatureReference(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferenceInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferenceInfo.java new file mode 100644 index 000000000..4c644583b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferenceInfo.java @@ -0,0 +1,19 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import java.util.List; + +/** + * Contains transformation parameters which are locally available. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface ReferenceInfo { + /** + * Gets the transformation info. + * + * @return The transformation info. + */ + public List getVerifyTransformsInfoProfiles(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferencesCheckResult.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferencesCheckResult.java new file mode 100644 index 000000000..7b5488613 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferencesCheckResult.java @@ -0,0 +1,23 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +/** + * Contains information about the verification status of references contained + * in the signature. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface ReferencesCheckResult { + /** + * Gets the check code. + * + * @return A numerical representation of the result of the reference check. + */ + public int getCode(); + /** + * Gets the additional information about the result. + * + * @return Additional information about the result. + */ + public ReferencesCheckResultInfo getInfo(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferencesCheckResultInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferencesCheckResultInfo.java new file mode 100644 index 000000000..be21b61c2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/ReferencesCheckResultInfo.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import org.w3c.dom.NodeList; + +/** + * Additional information contained in a <code>ReferencesCheckResult</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface ReferencesCheckResultInfo { + /** + * Gets the additional info of the failed <code>dsig:reference</code> element. + * + * @return The info elements. + */ + public NodeList getAnyOtherInfo(); + /** + * Gets the positions of the failed signature references containing the + * references to the manifests being described by this object. + * + * @return The positions of the failed signature references. + */ + public int[] getFailedReferences(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SignatureManifestCheckParams.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SignatureManifestCheckParams.java new file mode 100644 index 000000000..8f0efacf3 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SignatureManifestCheckParams.java @@ -0,0 +1,26 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import java.util.List; + +/** + * Contains parameters used to check the signature manifest. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface SignatureManifestCheckParams { + /** + * Gets the referential information. + * + * @return The referential information. + */ + public List getReferenceInfos(); + /** + * Gets information on whether signature source data should be returned. + * + * @return <code>true</code>, if signature source data should be returned, + * otherwise <code>false</code>. + */ + public boolean getReturnReferenceInputData(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfile.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfile.java new file mode 100644 index 000000000..569e691ca --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfile.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +/** + * Base class for supplementary information. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface SupplementProfile { + /** + * Indicates that this object contains explicit supplementary information. + */ + public static final int EXPLICIT_SUPPLEMENTPROFILE = 0; + /** + * Indicates that this object contains a profile id where supplementary + * information can be found. + */ + public static final int ID_SUPPLEMENTPROFILE = 1; + + /** + * Gets the type of supplementary information contained in this object. + * + * @return The type of supplementary information contained in this object, + * either <code>EXPLICIT_SUPPLEMENT</code> or <code>ID_SUPPLEMENT</code>. + */ + public int getSupplementProfileType(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfileExplicit.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfileExplicit.java new file mode 100644 index 000000000..7dd37a2d1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfileExplicit.java @@ -0,0 +1,19 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; + +/** + * Encapsulates explicit supplementary information. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface SupplementProfileExplicit extends SupplementProfile { + /** + * Gets the supplemental object. + * + * @return The supplemental object. + */ + public XMLDataObjectAssociation getSupplementProfile(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfileID.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfileID.java new file mode 100644 index 000000000..5b5083be9 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/SupplementProfileID.java @@ -0,0 +1,18 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +/** + * Encapsulates supplementary information stored in a profile. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface SupplementProfileID extends SupplementProfile { + /** + * Gets the id of the profile where the supplementary information can be + * found. + * + * @return The profile id. + */ + public String getSupplementProfileID(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameter.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameter.java new file mode 100644 index 000000000..3e173e0cd --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameter.java @@ -0,0 +1,40 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +/** + * Object encapsulating transform parameters either as a URI, binary or + * hashed. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface TransformParameter { + /** + * Indicates that this object contains a transform parameter given as + * a URI. + */ + public static final int URI_TRANSFORMPARAMETER = 0; + /** + * Indicates that this object contains binary transform parameter. + */ + public static final int BINARY_TRANSFORMPARAMETER = 1; + /** + * Indicatest that this object contains a binary hash of the transform + * parameter. + */ + public static final int HASH_TRANSFORMPARAMETER = 2; + + /** + * Gets the type of transform parameter contained in this object. + * + * @return The type of transform parameter, being one of + * <code>URI_TRANSFORMPARAMETER</code>, <code>BINARY_TRANSFORMPARAMETER</code> + * or <code>HASH_TRANSFORMPARAMETER</code>. + */ + public int getTransformParameterType(); + /** + * Gets the transform parameter URI. + * + * @return The transform parameter URI. + */ + public String getURI();} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterBinary.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterBinary.java new file mode 100644 index 000000000..600227dfd --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterBinary.java @@ -0,0 +1,21 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import java.io.InputStream; + +/** + * Encapsulates a binary transform parameter. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface TransformParameterBinary extends TransformParameter { + /** + * Gets the binary transform parameter. + * + * @return An <code>InputStream</code> from which the binary content can + * be read. + */ + public InputStream getBinaryContent(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterHash.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterHash.java new file mode 100644 index 000000000..ec45ea4f4 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterHash.java @@ -0,0 +1,26 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + + +/** + * Contains a hash of the transform parameter. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface TransformParameterHash extends TransformParameter { + /** + * Gets the method used for calculating the digest value. + * + * @return The digest method. + */ + public String getDigestMethod(); + /** + * Gets the binary hash of the transform parameter. + * + * @return A binary representation of the hash. + */ + public byte[] getDigestValue(); + + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterURI.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterURI.java new file mode 100644 index 000000000..4a6f0a58f --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/TransformParameterURI.java @@ -0,0 +1,12 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +/** + * Encapsulates a transform parameter given as a URI. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface TransformParameterURI extends TransformParameter { + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifySignatureInfo.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifySignatureInfo.java new file mode 100644 index 000000000..386651c47 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifySignatureInfo.java @@ -0,0 +1,27 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import at.gv.egovernment.moa.spss.api.common.Content; + +/** + * Encapsulates a signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifySignatureInfo { + /** + * Gets the content of the <code>VerifySignatureEnvironment</code> element. + * + * @return A <code>MOAElement</code> containing the + * <code>VerifySignatureEnvironment</code> in a DOM-like structure. + */ + public Content getVerifySignatureEnvironment(); + /** + * Gets the location of the signature. + * + * @return The location of the signature within the signature environment. + */ + public VerifySignatureLocation getVerifySignatureLocation(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifySignatureLocation.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifySignatureLocation.java new file mode 100644 index 000000000..f05e3e889 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifySignatureLocation.java @@ -0,0 +1,13 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import at.gv.egovernment.moa.spss.api.common.ElementSelector; + +/** + * Specifies where to find the signature to be verified. + * + * @author Patrick Peck + * @version $Id$ + */ +public interface VerifySignatureLocation extends ElementSelector { + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfile.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfile.java new file mode 100644 index 000000000..909fc58a2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfile.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +/** + * Object for explicitly specifying a transformation path. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyTransformsInfoProfile { + /** + * Indicates that this object contains the transformation path explicitly. + */ + public static final int EXPLICIT_VERIFYTRANSFORMSINFOPROFILE = 0; + /** + * Indicatest that this object contains a transformation info id. + */ + public static final int ID_VERIFYTRANSFORMSINFOPROFILE = 1; + + /** + * Gets the type of transformation information contained in this object. + * + * @return The type of transformation information, either + * <code>EXPLICIT_VERIFYTRANSFORMSINFOPROFILE</code> or + * <code>ID_VERIFYTRANSFORMSINFOPROFILE</code>. + */ + public int getVerifyTransformsInfoProfileType(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfileExplicit.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfileExplicit.java new file mode 100644 index 000000000..ff19683da --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfileExplicit.java @@ -0,0 +1,25 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import java.util.List; + +/** + * Encapsulates explicit transformation information. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyTransformsInfoProfileExplicit extends VerifyTransformsInfoProfile { + /** + * Gets the XMLDSig transforms element. + * + * @return The <code>List</code> of <code>Transform</code>s. + */ + public List getTransforms(); + /** + * Gets the transformation parameters. + * + * @return The transformation parameters. + */ + public List getTransformParameters(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfileID.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfileID.java new file mode 100644 index 000000000..0df3664da --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyTransformsInfoProfileID.java @@ -0,0 +1,18 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +/** + * Encapsulates transformation info id for signature verification. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyTransformsInfoProfileID extends VerifyTransformsInfoProfile { + /** + * Gets the identifier referencing the transformation info. + * + * @return The identifier referencing the transformation info. + */ + public String getVerifyTransformsInfoProfileID(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyXMLSignatureRequest.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyXMLSignatureRequest.java new file mode 100644 index 000000000..eb71f500b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyXMLSignatureRequest.java @@ -0,0 +1,55 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import java.util.Date; +import java.util.List; + + +/** + * Object that encapsulates a request to verify an XML signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyXMLSignatureRequest { + /** + * Gets the date and time for which the signature verification has to + * be performed. + * + * @return Date and time for which the signature verification has + * to be performed. + */ + public Date getDateTime(); + /** + * Gets the signature to be verified. + * + * @return The signature to be verified. + */ + public VerifySignatureInfo getSignatureInfo(); + /** + * Gets the supplemental information. + * + * @return The supplemental information. + */ + public List getSupplementProfiles(); + /** + * Gets parameters for Security Layer signature verification. + * + * @return Parameters for Security Layer signature verification. + */ + public SignatureManifestCheckParams getSignatureManifestCheckParams(); + /** + * Checks, whether actually signed data shall be returned. + * + * @return <code>true</code>, if signed data will be returned, + * otherwise <code>false</code>. + */ + public boolean getReturnHashInputData(); + /** + * Gets the profile id of the set of trusted certificates to be used for + * signature verification. + * + * @return The id of the trusted certificates. + */ + public String getTrustProfileId(); +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyXMLSignatureResponse.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyXMLSignatureResponse.java new file mode 100644 index 000000000..14ac71e67 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlverify/VerifyXMLSignatureResponse.java @@ -0,0 +1,60 @@ +package at.gv.egovernment.moa.spss.api.xmlverify; + +import java.util.List; + +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; + +/** + * Object that encapsulates the response on a request to verify an XML + * signature. + * + * @author Patrick Peck + * @author Stephan Grill + * @version $Id$ + */ +public interface VerifyXMLSignatureResponse { + /** + * Gets a <code>SignerInfo</code> element according to XMLDSig. + * + * @return A <code>SignerInfo</code> element according to XMLDSig. + */ + public SignerInfo getSignerInfo(); + /** + * Gets datas signed by the signatory. + * + * @return The signed datas. + */ + public List getHashInputDatas(); + /** + * Gets source datas elements. + * + * @return The source datas elements. + */ + public List getReferenceInputDatas(); + /** + * Gets the result of the signature verification. + * + * @return The result of the signature verification. + */ + public ReferencesCheckResult getSignatureCheck(); + /** + * Gets the result of the signature manifest verification. + * + * @return The result of the signature manifest verification. + */ + public ReferencesCheckResult getSignatureManifestCheck(); + /** + * Gets XMLDSigManifestCheck elements. + * + * @return The XMLDSigManifestCheck elements. + */ + public List getXMLDsigManifestChecks(); + /** + * Gets the result of the certification verification. + * + * @return The result of the certificate verification. + */ + public CheckResult getCertificateCheck(); + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/overview.htm b/spss.server/src/at/gv/egovernment/moa/spss/overview.htm new file mode 100644 index 000000000..9b17bbf91 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/overview.htm @@ -0,0 +1,155 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +</head> +<body bgcolor="white"> + +MOA SP/SS API documentation overview. + + +<h2>Using the MOA SP/SS API</h2> + +<h3>Invoking the services</h3> +In general, invoking the MOA SP/SS API involves the following steps: +<ol> +<li>Set the <code>moa.spss.server.configuration</code> system property to point +to the main MOA SP/SS configuration file. This needs to be done only once per +JVM instance. You may also call +{@link at.gv.egovernment.moa.spss.api.Configurator#init} at this point to +pre-initialize MOA SP/SS (if not, it is done automatically upon service +invocation).</li> +<li>Create an instance of the service to be used +({@link at.gv.egovernment.moa.spss.api.SignatureCreationService} or +{@link at.gv.egovernment.moa.spss.api.SignatureVerificationService}), +via its <code>getInstance()</code> method.</li> +<li>Create an instance of the +{@link at.gv.egovernment.moa.spss.api.SPSSFactory}, via its +{@link at.gv.egovernment.moa.spss.api.SPSSFactory#getInstance} method.</li> +<li>Use the <code>create...</code> methods of the <code>SPSSFactory</code> to +create the desired {@link at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest}, +{@link at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest} or +{@link at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest} object. +</li> +<li>Call one of the service methods: +{@link at.gv.egovernment.moa.spss.api.SignatureCreationService#createXMLSignature(at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest) <code>createXMLSignature()</code>}, +{@link at.gv.egovernment.moa.spss.api.SignatureVerificationService#verifyCMSSignature(at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest) <code>verifyCMSSignature()</code>} or +{@link at.gv.egovernment.moa.spss.api.SignatureVerificationService#verifyXMLSignature(at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest) <code>verifyXMLSignature()</code>}. +</li> +<li>Analyze the result of the service call, given as a +{@link at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse}, +{@link at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse} or +{@link at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse}. +In case of an error, a {@link at.gv.egovernment.moa.spss.MOAException} +is thrown by the service. Please be aware that errors during signature creation +are reported as part of a <code>CreateXMLSignatureResponse</code>. +</ol> + +<h3>Creating MOA SP/SS API objects</h3> +<p> +Invoking the MOA SP/SS API <code>Service</code> classes involves creating +a <code>Request</code> object using the {@link at.gv.egovernment.moa.spss.api.SPSSFactory SPSSFactory}. +Object creation using the <code>SPSSFactory</code> is always bottom-up, meaning +that in order to create an object all of its components must have been created +before. +</p> +<p> +The names of the MOA SP/SS API classes have been chosen to correspond to the +MOA SP/SS schema elements. The structure of the classes (i.e., their fields) +also corresponds to the structure of the respective MOA SP/SS schema elements. +However, a few classes escape this naming convention, mainly because the +corresponding schema elements contain <code>xsd:choice</code> components: +<ul> +<li>The various <code>Profile</code> classes have subclasses called +<code>ProfileID</code> and <code>ProfileExplicit</code> +(e.g., {@link at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileID} and +{@link at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileExplicit}), +so that the profile can be given either as an ID (which is to be resolved from the +MOA SP/SS configuration) or explicitly.</li> +<li>The classes {@link at.gv.egovernment.moa.spss.api.common.Content}, +{@link at.gv.egovernment.moa.spss.api.cmsverify.CMSContent} and +{@link at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter} have +subclasses specifying the type of content they actually contain. E.g., +{@link at.gv.egovernment.moa.spss.api.common.ContentBinary} will contain +a byte stream.</li> +</ul> + +</p> +<p> +For clarity, the MOA SP/SS API classes have been organized in several packages +listed in the following table: +</p> + +<table border=1 cellspacing=0 cellpadding=5> +<tr> + <td>Package</td><td>Purpose</td> +</tr> +<tr> + <td>{@link at.gv.egovernment.moa.spss.api.xmlsign}</td> + <td>Components of the {@link at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest} and + {@link at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse}</td> +</tr> +<tr> + <td>{@link at.gv.egovernment.moa.spss.api.cmsverify}</td> + <td>Components of the + {@link at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest} and + {@link at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse}</td> +</tr> +<tr> + <td>{@link at.gv.egovernment.moa.spss.api.xmlverify}</td> + <td>Components of the + {@link at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest} and + {@link at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse}</td> +</tr> +<tr> + <td>{@link at.gv.egovernment.moa.spss.api.common}</td> + <td>Common components used across the classes of the above packages</td> +</tr> +</table> + +<h3>Converting MOA SP/SS API objects to and from DOM trees</h3> +The package {@link at.gv.egovernment.moa.spss.api.xmlbind} contains helper +classes to: +<ul> +<li>Parse a DOM tree containing a <code>CreateXMLSignatureRequest</code>, +<code>VerifyCMSSignatureRequest</code> or +<code>VerifyCMSSignatureRequest</code> into its respective MOA SP/SS API object +representation. For example, to parse a <code>CreateXMLSignatureRequest</code> +DOM tree, the {@link at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureRequestParser#parse(org.w3c.dom.Element) CreateXMLSignatureRequestParser.parse()} +method can be used. <br /> +<b>Note:</b> The DOM tree of the request must be derived from a schema valid +XML document. Otherwise, unexpected behaviour will almost certainly result.</li> +<li>Build a <code>CreateXMLSignatureResponse</code>, +<code>VerifyCMSSignatureResponse</code> or a +<code>VerifyXMLSignatureResponse</code> DOM tree from the respective MOA SP/SS +API object. For example, to build a <code>VerifyXMLSignatureResponse</code> +DOM tree, the {@link at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder#build(at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse) VerifyXMLSignatureResponseBuilder.build()} +can be used.<br /> +<b>Note:</b>The serialized DOM tree will be schema valid. +</li> +</ul> +The DOM trees can easily be read from and written to XML byte streams using +the methods in the {@link at.gv.egovernment.moa.util.DOMUtils} class. +<br /> + +<h3>Utilities and Logging</h3> +<p> The packages {@link at.gv.egovernment.moa.util} and +{@link at.gv.egovernment.moa.spss.util} contain utility classes developed for +the MOA SP/SS implementation. Since the classes contained in these packages are +tailored towards the MOA SP/SS implementation, they are far from being complete +in the sense of providing a utility class library. Therefore, they may or may +not prove useful in the context of your application. Their interfaces may also +change in future releases. +</p> + +<p>The package {@link at.gv.egovernment.moa.logging} contains classes for +logging messages to the MOA SP/SS log hierarchy via the +{@link at.gv.egovernment.moa.logging.Logger} class. +</p> + +<h3>Related Documentation</h3> + +See also the <a href="../moa_spss/sp-anwendung.htm#API">API example</a> in the +MOA SP/SS documentation. + +</body> +</html>
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationException.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationException.java new file mode 100644 index 000000000..f2b847053 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationException.java @@ -0,0 +1,34 @@ +package at.gv.egovernment.moa.spss.server.config; + +import at.gv.egovernment.moa.spss.MOASystemException; + +/** + * Exception signalling an error in the configuration. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ConfigurationException extends MOASystemException { + + /** + * Create a <code>ConfigurationException</code>. + * + * @see at.gv.egovernment.moa.spss.server.MOAException#MOAException(String, Object[]) + */ + public ConfigurationException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + /** + * Create a <code>ConfigurationException</code>. + * @see at.gv.egovernment.moa.spss.server.MOAException#MOAException(String, Object[], Throwable) + */ + public ConfigurationException( + String messageId, + Object[] parameters, + Throwable wrapped) { + + super(messageId, parameters, wrapped); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java new file mode 100644 index 000000000..1e966911b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java @@ -0,0 +1,956 @@ +package at.gv.egovernment.moa.spss.server.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.traversal.NodeIterator; + +import org.xml.sax.SAXException; + +import iaik.ixsil.exceptions.URIException; +import iaik.ixsil.util.URI; +import iaik.pki.pathvalidation.ChainingModes; +import iaik.utils.RFC2253NameParser; +import iaik.utils.RFC2253NameParserException; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A class that builds configuration data from a DOM based representation. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ConfigurationPartsBuilder { + + // + // XPath namespace prefix shortcuts + // + + private static final String CONF = Constants.MOA_CONFIG_PREFIX + ":"; + private static final String DSIG = Constants.DSIG_PREFIX + ":"; + + // + // chaining mode constants appearing in the configuration file + // + + private static final String CM_CHAINING = "chaining"; + private static final String CM_PKIX = "pkix"; + + // + // XPath expressions to select certain parts of the configuration + // + + private static final String ROOT = "/" + CONF + "MOAConfiguration/"; + private static final String DIGEST_METHOD_XPATH = + ROOT + CONF + "DigestMethodAlgorithm/@name"; + private static final String C14N_ALGORITHM_XPATH = + ROOT + CONF + "CanonicalizationAlgorithm/@name"; + private static final String HARDWARE_CRYPTO_MODULE_XPATH = + ROOT + CONF + "HardwareCryptoModule"; + private static final String HARDWARE_KEY_XPATH = + ROOT + CONF + "HardwareKeyModule"; + private static final String SOFTWARE_KEY_XPATH = + ROOT + CONF + "SoftwareKeyModule"; + private static final String KEYGROUP_XPATH = ROOT + CONF + "KeyGroup"; + private static final String KEY_XPATH = CONF + "Key"; + private static final String KEY_MODULE_ID_XPATH = CONF + "KeyModuleID"; + private static final String KEY_CERT_XPATH = CONF + "KeyCertIssuerSerial"; + private static final String KEYGROUP_MAPPING_XPATH = + ROOT + CONF + "KeyGroupMapping"; + private static final String KEYGROUP_MAPPING_KEYGROUP_XPATH = + CONF + "KeyGroup"; + private static final String ISSUER_SERIAL_XPATH = CONF + "X509IssuerSerial"; + private static final String ISSUER_XPATH = DSIG + "X509IssuerName"; + private static final String SERIAL_XPATH = DSIG + "X509SerialNumber"; + private static final String CHAINING_MODES_XPATH = + ROOT + CONF + "ChainingModes"; + private static final String CHAINING_MODES_DEFAULT_XPATH = + CHAINING_MODES_XPATH + "/@systemDefaultMode"; + private static final String TRUST_ANCHOR_XPATH = + ROOT + CONF + "ChainingModes/" + CONF + "TrustAnchor"; + private static final String CRL_DISTRIBUTION_POINT_XPATH = + ROOT + CONF + "CRLDistributionPoint"; + private static final String CA_ISSUER_DN_XPATH = CONF + "CAIssuerDN"; + private static final String DISTRIBUTION_POINT_XPATH = + CONF + "DistributionPoint"; + private static final String CRL_ARCHIVE_XPATH = ROOT + CONF + "CRLArchive"; + private static final String GENERIC_CONFIGURATION_XPATH = + ROOT + CONF + "GenericConfiguration"; + private static final String CREATE_TRANSFORMS_INFO_PROFILE_XPATH = + ROOT + CONF + "CreateTransformsInfoProfile"; + private static final String CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH = + ROOT + CONF + "CreateSignatureEnvironmentProfile"; + private static final String VERIFY_TRANSFORMS_INFO_PROFILE_XPATH = + ROOT + CONF + "VerifyTransformsInfoProfile"; + private static final String SUPPLEMENT_PROFILE_XPATH = + ROOT + CONF + "SupplementProfile"; + private static final String TRUST_PROFILE_XPATH = + ROOT + CONF + "TrustProfile"; + + // + // default values for configuration parameters + // + + /** The accepted canonicalization algorithm URIs, as an array */ + private static final String[] ACCEPTED_C14N_ALGORITHMS_ARRAY = + { + Constants.C14N_URI, + Constants.C14N_WITH_COMMENTS_URI, + Constants.EXC_C14N_URI, + Constants.EXC_C14N_WITH_COMMENTS_URI }; + + /** The accepted canonicalization algorithm URIs, as a Set */ + private static final Set ACCEPTED_C14N_ALGORITHMS = + new HashSet(Arrays.asList(ACCEPTED_C14N_ALGORITHMS_ARRAY)); + + /** Default canonicalization algorithm, if none/illegal has been configured */ + private static final String C14N_ALGORITHM_DEFAULT = Constants.C14N_URI; + + /** The accepted digest method algorithm URIs, as an array */ + private static final String[] ACCEPTED_DIGEST_ALGORITHMS_ARRAY = + { Constants.SHA1_URI }; + + /** The accepted digest method algorithm URIs, as a Set */ + private static final Set ACCEPTED_DIGEST_ALGORITHMS = + new HashSet(Arrays.asList(ACCEPTED_DIGEST_ALGORITHMS_ARRAY)); + + /** Default digest algorithm URI, if none/illegal has been configured */ + private static final String DIGEST_ALGORITHM_DEFAULT = Constants.SHA1_URI; + + /** The root element of the MOA configuration */ + private Element configElem; + + /** Whether any warnings were encountered building the configuration. */ + private List warnings = new ArrayList(); + + /** + * Create a new <code>ConfigurationPartsBuilder</code>. + * + * @param configElem The root element of the MOA configuration. + */ + public ConfigurationPartsBuilder(Element configElem) { + this.configElem = configElem; + } + + /** + * Returns the root element of the MOA configuration. + * + * @return The root element of the MOA configuration. + */ + public Element getConfigElem() { + return configElem; + } + + /** + * Returns the warnings encountered during building the configuration. + * + * @return A <code>List</code> of <code>String</code>s, containing the + * warning messages. + */ + public List getWarnings() { + return warnings; + } + + /** + * Returns the digest method algorithm name. + * + * @return The digest method algorithm name from the configuration. + */ + public String getDigestMethodAlgorithmName() { + String digestMethod = + getAttributeValue(getConfigElem(), DIGEST_METHOD_XPATH, null); + + if (digestMethod == null + || !ACCEPTED_DIGEST_ALGORITHMS.contains(digestMethod)) { + warn( + "config.23", + new Object[] { "DigestMethodAlgorithm", DIGEST_ALGORITHM_DEFAULT }); + digestMethod = DIGEST_ALGORITHM_DEFAULT; + } + + return digestMethod; + } + + /** + * Returns the canonicalization algorithm name. + * + * @return The canonicalization algorithm name from the configuration. + */ + public String getCanonicalizationAlgorithmName() { + String c14nAlgorithm = + getAttributeValue(getConfigElem(), C14N_ALGORITHM_XPATH, null); + + if (c14nAlgorithm == null + || !ACCEPTED_C14N_ALGORITHMS.contains(c14nAlgorithm)) { + warn( + "config.23", + new Object[] { "CanonicalizationAlgorithm", C14N_ALGORITHM_DEFAULT }); + c14nAlgorithm = C14N_ALGORITHM_DEFAULT; + } + + return c14nAlgorithm; + } + + /** + * Build the mapping of generic configuration properties. + * + * @return The mapping of generic configuration properties (a name to value + * mapping) from the configuration. + */ + public Map buildGenericConfiguration() { + Map genericConfiguration = new HashMap(); + NodeIterator gcIter = + XPathUtils.selectNodeIterator( + getConfigElem(), + GENERIC_CONFIGURATION_XPATH); + Element gcElem; + + while ((gcElem = (Element) gcIter.nextNode()) != null) { + String gcName = gcElem.getAttribute("name"); + String gcValue = gcElem.getAttribute("value"); + + if (genericConfiguration.containsKey(gcName)) { + warn("config.24", new Object[] { gcName }); + } else { + genericConfiguration.put(gcName, gcValue); + } + } + + return genericConfiguration; + } + + /** + * Build the configured hardware crypto modules. + * + * @return The hardware crypto modules from the configuration. + */ + public List buildHardwareCryptoModules() { + List modules = new ArrayList(); + NodeIterator modIter = + XPathUtils.selectNodeIterator( + getConfigElem(), + HARDWARE_CRYPTO_MODULE_XPATH); + Element modElem; + + while ((modElem = (Element) modIter.nextNode()) != null) { + String name = modElem.getAttribute("name"); + String slotID = modElem.getAttribute("slotID"); + String userPIN = modElem.getAttribute("userPIN"); + HardwareCryptoModule module = + new HardwareCryptoModule(name, slotID, userPIN); + modules.add(module); + } + + return modules; + } + + /** + * Build the configured hardware keys. + * + * @param The keyModules that the configuration already knows about. To + * prevent multiple key modules with the same ID. + * @return The hardware keys contained in the configuration. + */ + public List buildHardwareKeyModules(List keyModules) { + Set existingIds = toIdSet(keyModules); + List hardwareKeys = new ArrayList(); + NodeIterator hkIter = + XPathUtils.selectNodeIterator(getConfigElem(), HARDWARE_KEY_XPATH); + Element keyElem; + + while ((keyElem = (Element) hkIter.nextNode()) != null) { + String id = keyElem.getAttribute("id"); + String name = keyElem.getAttribute("name"); + String slotID = keyElem.getAttribute("slotID"); + String userPIN = keyElem.getAttribute("userPIN"); + + if (existingIds.contains(id)) { + warn( + "config.04", + new Object[] { "Hardware- oder SoftwareKeyModule", id }); + } else { + KeyModule key = new HardwareKeyModule(id, name, slotID, userPIN); + hardwareKeys.add(key); + existingIds.add(id); + } + + } + + return hardwareKeys; + } + + /** + * Build the configured software keys. + * + * @param The keyModules that the configuration already knows about. To + * prevent multiple key modules with the same ID. + * @param configRoot The directory containing the main configuration file. + * Used to resolve keystore files configured using a relative URI. + * @return The software keys contained in the configuration. + */ + public List buildSoftwareKeyModules(List keyModules, File configRoot) { + Set existingIds = toIdSet(keyModules); + List softwareKeys = new ArrayList(); + NodeIterator skIter = + XPathUtils.selectNodeIterator(getConfigElem(), SOFTWARE_KEY_XPATH); + + Element keyElem; + + while ((keyElem = (Element) skIter.nextNode()) != null) { + String id = keyElem.getAttribute("id"); + String fileName = keyElem.getAttribute("filename"); + String passWord = keyElem.getAttribute("password"); + + if (existingIds.contains(id)) { + warn( + "config.04", + new Object[] { "Hardware- oder SoftwareKeyModule", id }); + } else { + File keyFile; + KeyModule key; + + // make keyFile absolute + keyFile = new File(fileName); + if (!keyFile.isAbsolute()) { + keyFile = new File(configRoot, fileName); + } + + // check for existence + if (!keyFile.exists() || keyFile.isDirectory()) { + warn("config.25", new Object[] { id, keyFile.getAbsolutePath()}); + } else { + // create a new key module + key = new SoftwareKeyModule(id, keyFile.getAbsolutePath(), passWord); + softwareKeys.add(key); + existingIds.add(id); + } + } + + } + + return softwareKeys; + } + + /** + * Build the key group configuration. + * + * @param keyModules The <code>KeyModule</code>s that the configuration + * knows about. Used to check for errors in the configuration. + * @return The mapping between key group IDs and key groups. + */ + public Map buildKeyGroups(List keyModules) { + Set keyModuleIds = toIdSet(keyModules); + Map keyGroups = new HashMap(); + NodeIterator kgIter; + Element keyGroupElem; + + // select all KeyGroup elements and build the KeyGroup objects from them + kgIter = XPathUtils.selectNodeIterator(getConfigElem(), KEYGROUP_XPATH); + while ((keyGroupElem = (Element) kgIter.nextNode()) != null) { + String keyGroupId = keyGroupElem.getAttribute("id"); + Set keyGroupEntries = + buildKeyGroupEntries(keyGroupId, keyModuleIds, keyGroupElem); + KeyGroup keyGroup = new KeyGroup(keyGroupId, keyGroupEntries); + + if (keyGroups.containsKey(keyGroupId)) { + warn("config.04", new Object[] { "KeyGroup", keyGroupId }); + } else { + keyGroups.put(keyGroup.getId(), keyGroup); + } + } + + return keyGroups; + } + + /** + * Return the set of IDs contained in the given <code>KeyModule</code>s. + * + * @param keyModules The <code>KeyModule</code>s from which to extract the + * IDs. + * @return The IDs from the given <code>KeyModule</code>s. + */ + private Set toIdSet(List keyModules) { + Set ids = new HashSet(); + Iterator iter; + + for (iter = keyModules.iterator(); iter.hasNext();) { + KeyModule keyModule = (KeyModule) iter.next(); + ids.add(keyModule.getId()); + } + + return ids; + } + + /** + * Build the key entries belonging to a key group. + * + * @param keyGroupId The ID of the key group we are building here. Passed + * for logging purposes. + * @param keyModuleIds The IDs of the <code>HardwareKeyModule</code>s and + * <code>SoftwareKeyModule</code>s that exist in the configuration. + * @param keyGroupElem The <code>KeyGroup</code> DOM element to parse. + * @return A <code>Set</code> of <code>KeyGroupEntry</code> objects. + */ + private Set buildKeyGroupEntries( + String keyGroupId, + Set keyModuleIds, + Element keyGroupElem) { + + Set entries = new HashSet(); + NodeIterator keyEntryIter; + Element keyEntryElem; + + // select all Key elements and put them into the Map + keyEntryIter = XPathUtils.selectNodeIterator(keyGroupElem, KEY_XPATH); + while ((keyEntryElem = (Element) keyEntryIter.nextNode()) != null) { + String keyModuleId = + getElementValue(keyEntryElem, KEY_MODULE_ID_XPATH, ""); + Element keyCertElem = + (Element) XPathUtils.selectSingleNode(keyEntryElem, KEY_CERT_XPATH); + IssuerAndSerial issuerSerial = buildIssuerAndSerial(keyCertElem); + + if (!keyModuleIds.contains(keyModuleId)) { + warn("config.26", new Object[] { keyGroupId, keyModuleId }); + } else if (issuerSerial != null) { + KeyGroupEntry entry = new KeyGroupEntry(keyModuleId, issuerSerial); + entries.add(entry); + } + } + return entries; + } + + /** + * Build the key group mapping. + * + * @param keyGroups The available key groups. + * @param anonymous The <code>IssuerAndSerial</code> to be used for key group + * mappings not protected by a certificate. + * @return The key group mapping. + */ + public Map buildKeyGroupMappings(Map keyGroups, IssuerAndSerial anonymous) { + Map mappings = new HashMap(); + NodeIterator mappingIter; + Element mappingElem; + + // select all KeyGroupMapping elements + mappingIter = + XPathUtils.selectNodeIterator(getConfigElem(), KEYGROUP_MAPPING_XPATH); + + // build the mapping for each KeyGroupMapping element + while ((mappingElem = (Element) mappingIter.nextNode()) != null) { + Element issuerSerialElem = + (Element) XPathUtils.selectSingleNode(mappingElem, ISSUER_SERIAL_XPATH); + IssuerAndSerial issuerAndSerial; + + // build the IssuerAndSerial who has access to the key groups + if (issuerSerialElem != null) { + issuerAndSerial = buildIssuerAndSerial(issuerSerialElem); + } else { + // IssuerSerial element: the keygroup is generally available + issuerAndSerial = anonymous; + } + + // add the key groups to the mappings + if (issuerAndSerial != null) { + Map groups = (Map) mappings.get(issuerAndSerial); + NodeIterator keyGroupIter; + Element keyGroupElem; + + if (groups == null) { + // no mapping exist -> build one + groups = new HashMap(); + mappings.put(issuerAndSerial, groups); + } + + // select the available key groups and add them to the mapping + keyGroupIter = + XPathUtils.selectNodeIterator( + mappingElem, + KEYGROUP_MAPPING_KEYGROUP_XPATH); + while ((keyGroupElem = (Element) keyGroupIter.nextNode()) != null) { + String keyGroupId = keyGroupElem.getAttribute("id"); + KeyGroup keyGroup = (KeyGroup) keyGroups.get(keyGroupId); + + if (keyGroup != null) { + groups.put(keyGroupId, keyGroup); + } else { + warn("config.00", new Object[] { keyGroupId }); + } + } + } + } + + return mappings; + } + + /** + * Returns the default chaining mode from the configuration. + * + * @return The default chaining mode. + */ + public String getDefaultChainingMode() { + String defaultChaining = + getAttributeValue( + getConfigElem(), + CHAINING_MODES_DEFAULT_XPATH, + CM_CHAINING); + + return translateChainingMode(defaultChaining); + + } + + /** + * Build the chaining modes for all configured trust anchors. + * + * @return The mapping from trust anchors to chaining modes. + */ + public Map buildChainingModes() { + Map chainingModes = new HashMap(); + NodeIterator trustIter = + XPathUtils.selectNodeIterator(getConfigElem(), TRUST_ANCHOR_XPATH); + Element trustAnchorElem; + + while ((trustAnchorElem = (Element) trustIter.nextNode()) != null) { + IssuerAndSerial issuerAndSerial = buildIssuerAndSerial(trustAnchorElem); + String mode = trustAnchorElem.getAttribute("mode"); + + if (issuerAndSerial != null) { + chainingModes.put(issuerAndSerial, translateChainingMode(mode)); + } + } + + return chainingModes; + } + + /** + * Build an <code>IssuerAndSerial</code> from the DOM representation. + * + * @param root The root element (being of type <code>dsig: + * X509IssuerSerialType</code>. + * @return The issuer and serial number contained in the <code>root</code> + * element or <code>null</code> if could not be built for any reason. + */ + private IssuerAndSerial buildIssuerAndSerial(Element root) { + String issuer = getElementValue(root, ISSUER_XPATH, null); + String serial = getElementValue(root, SERIAL_XPATH, null); + + if (issuer != null && serial != null) { + try { + RFC2253NameParser nameParser = new RFC2253NameParser(issuer); + Principal issuerDN = nameParser.parse(); + + return new IssuerAndSerial(issuerDN, new BigInteger(serial)); + } catch (RFC2253NameParserException e) { + warn("config.16", new Object[] { issuer, serial }, e); + return null; + } catch (NumberFormatException e) { + warn("config.16", new Object[] { issuer, serial }, e); + return null; + } + } + return null; + } + + /** + * Translate the chaining mode from the configuration file to one used in the + * IAIK MOA API. + * + * @param chainingMode The chaining mode from the configuration. + * @return The chaining mode as provided by the <code>ChainingModes</code> + * interface. + * @see iaik.pki.pathvalidation.ChainingModes + */ + private String translateChainingMode(String chainingMode) { + if (chainingMode.equals(CM_CHAINING)) { + return ChainingModes.CHAIN_MODE; + } else if (chainingMode.equals(CM_PKIX)) { + return ChainingModes.PKIX_MODE; + } else { + return ChainingModes.CHAIN_MODE; + } + } + + /** + * Build the CRL distribution points mapping. + * + * @return The mapping from certificate authorities to distribution points. + */ + public Map buildCRLDistributionPoints() { + Map crlDps = new HashMap(); + NodeIterator crlDpIter; + Element crlDpElem; + + // select all CRLDistributionPoint elements and build the + // CRLDistributionPoints + crlDpIter = + XPathUtils.selectNodeIterator( + getConfigElem(), + CRL_DISTRIBUTION_POINT_XPATH); + + // build the mapping of CA name to distribution points + while ((crlDpElem = (Element) crlDpIter.nextNode()) != null) { + String caIssuerDNText = + getElementValue(crlDpElem, CA_ISSUER_DN_XPATH, ""); + RFC2253NameParser nameParser = new RFC2253NameParser(caIssuerDNText); + NodeIterator dpIter = + XPathUtils.selectNodeIterator(crlDpElem, DISTRIBUTION_POINT_XPATH); + String caIssuerDN; + Set dps; + Element dpElem; + + try { + caIssuerDN = nameParser.parse().getName(); + + // check, if a mapping exists or make a new mapping + dps = (Set) crlDps.get(caIssuerDN); + if (dps == null) { + dps = new HashSet(); + crlDps.put(caIssuerDN, dps); + } + + // add the distribution points of this CA to the set + while ((dpElem = (Element) dpIter.nextNode()) != null) { + DistributionPoint dp = buildDistributionPoint(dpElem); + dps.add(dp); + } + } catch (RFC2253NameParserException e) { + warn("config.13", new Object[] { caIssuerDNText }, e); + } + + } + + return crlDps; + } + + /** + * Build a distribution point from the DOM representation. + * + * @param dpElem The root element of the distribution point. + * @return The distribution point. + */ + private DistributionPoint buildDistributionPoint(Element dpElem) { + String uri = dpElem.getAttribute("uri"); + String reasonCodes = dpElem.getAttribute("reasonCodes"); + + return new DistributionPoint(uri, reasonCodes != null ? reasonCodes : ""); + } + + /** + * Return the CRL archive duration. + * + * @return The value of the CRL archive duration setting from the + * configuration. + */ + public int getCRLArchiveDuration() { + Element crlArchiveElem = + (Element) XPathUtils.selectSingleNode(getConfigElem(), CRL_ARCHIVE_XPATH); + String crlArchiveDuration; + + if (crlArchiveElem == null) { + return 0; + } + + try { + crlArchiveDuration = crlArchiveElem.getAttribute("duration"); + return Integer.parseInt(crlArchiveDuration); + } catch (NumberFormatException e) { + warn("config.01", null); + return 0; + } + } + + /** + * Build the <code>CreateTransformsInfoProfile</code>s. + * + * @param configRoot The directory of the main configuration file. Used for + * lookup of profiles with relative file names. + * @return The mapping from profile ID to profile. + */ + public Map buildCreateTransformsInfoProfiles(File configRoot) { + return loadProfiles( + configRoot, + CREATE_TRANSFORMS_INFO_PROFILE_XPATH, + "CreateTransformsInfoProfile"); + } + + /** + * Build the <code>CreateSignatureEnvironmentProfile</code>s. + * + * @param configRoot The directory of the main configuration file. Used for + * lookup of profiles with relative file names. + * @return The mapping from profile ID to profile. + */ + public Map buildCreateSignatureEnvironmentProfiles(File configRoot) { + return loadProfiles( + configRoot, + CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH, + "CreateSignatureEnvironmentProfile"); + } + + /** + * Build the <code>VerifyTransformsInfoProfile</code>s. + * + * @param configRoot The directory of the main configuration file. Used for + * lookup of profiles with relative file names. + * @return The mapping from profile ID to profile. + */ + public Map buildVerifyTransformsInfoProfiles(File configRoot) { + return loadProfiles( + configRoot, + VERIFY_TRANSFORMS_INFO_PROFILE_XPATH, + "VerifyTransformsInfoProfile"); + } + + /** + * Build the <code>SupplementProfile</code>s. + * + * @param configRoot The directory of the main configuration file. Used for + * lookup of profiles with relative file names. + * @return The mapping from profile ID to profile. + */ + public Map buildSupplementProfiles(File configRoot) { + return loadProfiles( + configRoot, + SUPPLEMENT_PROFILE_XPATH, + "SupplementProfile"); + } + + /** + * Load a profile mapping. + * + * @param root The absolute directory path of the main configuration file. + * @param xpath The XPath to select the profiles from the configuration. + * @param profileRoot The name of the profile root element. + * @return Map The profile ID to profile mapping. + */ + private Map loadProfiles(File root, String xpath, String profileRoot) { + Map profiles = new HashMap(); + NodeIterator profileIter = + XPathUtils.selectNodeIterator(getConfigElem(), xpath); + Element profileElem; + + while ((profileElem = (Element) profileIter.nextNode()) != null) { + String id = profileElem.getAttribute("id"); + String fileName = profileElem.getAttribute("filename"); + + if (profiles.containsKey(id)) { + warn("config.04", new Object[] { profileRoot, id }); + } else { + Element profile; + + try { + File profileFile = new File(fileName); + + // make profileFile absolute + if (!profileFile.isAbsolute()) { + profileFile = new File(root, fileName); + } + + // load the profile + info( + "config.22", + new Object[] { profileRoot, id, profileFile.getAbsoluteFile()}); + profile = loadProfile(profileFile); + + if (profile.getTagName().equals(profileRoot)) { + profiles.put(id, profile); + } else { + warn("config.02", new Object[] { profileRoot, id, fileName }); + } + } catch (ConfigurationException e) { + warn("config.03", new Object[] { profileRoot, id }); + } + } + + } + + return profiles; + } + + /** + * Load a profile from a file. + * + * @param root The absolute directory path of the main configuration file. + * @param profileFile The file containing the profile. + * @return The profile in its DOM representation. + * @throws ConfigurationException An error occurred loading the profile. + */ + private Element loadProfile(File profileFile) throws ConfigurationException { + + Element profile; + + try { + profile = parseXml(new FileInputStream(profileFile)); + } catch (Exception e) { + throw new ConfigurationException("config.12", null, e); + } + + return profile; + } + + /** + * Bulid the trust profile mapping. + * + * @param configRoot The absolute path to the main configuration file. + * @return The profile ID to profile mapping. + */ + public Map buildTrustProfiles(File configRoot) { + Map trustProfiles = new HashMap(); + NodeIterator profileIter = + XPathUtils.selectNodeIterator(getConfigElem(), TRUST_PROFILE_XPATH); + Element profileElem; + + while ((profileElem = (Element) profileIter.nextNode()) != null) { + String id = profileElem.getAttribute("id"); + String uriStr = profileElem.getAttribute("uri"); + + try { + URI uri = new URI(uriStr); + TrustProfile profile; + File profileDir; + + if (!uri.isAbsolute()) { // make it absolute to the config file + uri = new URI(configRoot.toURL() + uriStr); + } + + profileDir = new File(uri.getPath()); + if (!profileDir.exists() || !profileDir.isDirectory()) { + warn("config.27", new Object[] { id }); + } + + if (trustProfiles.containsKey(id)) { + warn("config.04", new Object[] { "TrustProfile", id }); + } else { + profile = new TrustProfile(id, uri.toString()); + trustProfiles.put(id, profile); + } + + } catch (URIException e) { + warn("config.14", new Object[] { id, uriStr }, e); + } catch (MalformedURLException e) { + warn("config.15", null, e); + } + } + + return trustProfiles; + } + + // + // various utility methods + // + + /** + * Parse a configuration XML file. + * + * @param inputStream The stream from which to read the XML data. + * @return The DOM representation of the XML data. + * @throws ParserConfigurationException XML parser not configured properly. + * @throws SAXException An error parsing the XML file. + * @throws IOException An error reading the stream. + */ + private static Element parseXml(InputStream inputStream) + throws ParserConfigurationException, SAXException, IOException { + return DOMUtils + .parseDocument(inputStream, true, Constants.ALL_SCHEMA_LOCATIONS, null) + .getDocumentElement(); + } + + /** + * Return the value of an element located by an XPath. + * + * @param root The root element from which to evaluate the <code>xpath</code>. + * @param xpath The XPath pointing to the element. + * @param def The default value, if no element can be found with the given + * <code>xpath</code>. + * @return The element value or <code>def</code>, if the element cannot be + * found. + */ + private String getElementValue(Element root, String xpath, String def) { + + Element elem = (Element) XPathUtils.selectSingleNode(root, xpath); + return elem != null ? DOMUtils.getText(elem) : def; + } + + /** + * Return the value of an attribute located by an XPath. + * + * @param root The root element from which to evaluate the <code>xpath</code>. + * @param xpath The XPath pointing to the attribute. + * @param def The default value, if no attribute can be found with the given + * <code>xpath</code>. + * @return The element value or <code>def</code>, if the attribute cannot be + * found. + */ + private String getAttributeValue(Element root, String xpath, String def) { + Attr attr = (Attr) XPathUtils.selectSingleNode(root, xpath); + return attr != null ? attr.getValue() : def; + } + + /** + * Log an info message. + * + * @param messageId The message ID. + * @param parameters Additional parameters for the message. + * @see at.gv.egovernment.moa.spss.server.util.MessageProvider + */ + private static void info(String messageId, Object[] parameters) { + MessageProvider msg = MessageProvider.getInstance(); + Logger.info(new LogMsg(msg.getMessage(messageId, parameters))); + } + + /** + * Log a warning. + * + * @param messageId The message ID. + * @param args Additional parameters for the message. + * @see at.gv.egovernment.moa.spss.server.util.MessageProvider + */ + private void warn(String messageId, Object[] args) { + MessageProvider msg = MessageProvider.getInstance(); + String txt = msg.getMessage(messageId, args); + + Logger.warn(new LogMsg(txt)); + warnings.add(txt); + } + + /** + * Log a warning. + * + * @param messageId The message ID. + * @param args Additional parameters for the message. + * @param t An exception being the cause of the warning. + * @see at.gv.egovernment.moa.spss.server.util.MessageProvider + */ + private void warn(String messageId, Object[] args, Throwable t) { + MessageProvider msg = MessageProvider.getInstance(); + String txt = msg.getMessage(messageId, args); + + Logger.warn(new LogMsg(txt), t); + warnings.add(txt); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationProvider.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationProvider.java new file mode 100644 index 000000000..fbae33b72 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationProvider.java @@ -0,0 +1,666 @@ +package at.gv.egovernment.moa.spss.server.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.net.URL; +import java.security.Principal; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Element; + +import iaik.asn1.structures.Name; +import iaik.utils.RFC2253NameParser; +import iaik.utils.RFC2253NameParserException; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; + +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A class providing access to the MOA configuration data. + * + * <p>Configuration data is read from an XML file, whose location is given by + * the <code>moa.spss.server.configuration</code> system property.</p> + * <p>This class implements the Singleton pattern. The <code>reload()</code> + * method can be used to update the configuration data. Therefore, it is not + * guaranteed that consecutive calls to <code>getInstance()</code> will return + * the same <code>ConfigurationProvider</code> all the time. During the + * processing of a web service request, the current + * <code>TransactionContext</code> should be used to obtain the + * <code>ConfigurationProvider</code> local to that request.</p> + * + * @author Patrick Peck + * @author Sven Aigner + * @version $Id$ + */ +public class ConfigurationProvider { + + /** + * The name of the system property which contains the file name of the + * configuration file. + */ + public static final String CONFIG_PROPERTY_NAME = + "moa.spss.server.configuration"; + + /** + * The name of the generic configuration property giving the root directory of + * a directory based cert store. + */ + public static final String DIRECTORY_CERTSTORE_PARAMETER_PROPERTY = + "DirectoryCertStoreParameters.RootDir"; + + /** The name of the generic configuration property which determines if + * certificates should be added to the cert store automatically. */ + public static final String AUTO_ADD_CERTIFICATES_PROPERTY = + "autoAddCertificates"; + + /** The name of the generic configuration property whether the authority + * info access should be used. */ + public static final String USE_AUTHORITY_INFO_ACCESS_PROPERTY = + "useAuthorityInfoAccess"; + + /** The name of the generic configuration property determining the maximum + * age of CRL entries. */ + public static final String MAX_REVOCATION_AGE_PROPERTY = "maxRevocationAge"; + + /** + * The name of the generic configuration property giving the database URL of + * the CRL archive. + */ + public static final String DATABASE_ARCHIVE_PARAMETER_PROPERTY = + "DataBaseArchiveParameter.JDBCUrl"; + + /** The name of the generic configuration property determining whether + * to check the revocation status of signer certificates. */ + public static final String REVOCATION_CHECKING_PROPERTY = "checkRevocation"; + + /** The name of the generic configuration property determining whether to + * archive revocation information. */ + public static final String ARCHIVE_REVOCATION_INFO_PROPERTY = + "archiveRevocationInfo"; + + /** The name of the generic configuration property used for setting the + * signing time to a predefined value. (Use for testing purposes only). */ + public static final String TEST_SIGNING_TIME_PROPERTY = "test.SigningTime"; + + /** + * A fake <code>IssuerAndSerial</code> object for storing KeyGroup information + * accessible by all clients. + */ + private static final IssuerAndSerial ANONYMOUS_ISSUER_SERIAL = + new IssuerAndSerial(new Name(), new BigInteger("0")); + + /** Singleton instance. <code>null</code>, if none has been created. */ + private static ConfigurationProvider instance; + + // + // configuration data + // + + /** The warnings generated when building the configuration. */ + private List warnings = new ArrayList(); + + /** The default digest method algorithm name */ + private String digestMethodAlgorithmName; + + /** The default canonicalization algorithm name */ + private String canonicalizationAlgorithmName; + + /** + * A <code>Map</code> which contains generic configuration information. Maps a + * configuration name (a <code>String</code>) to a configuration value (also a + * <code>String</code>). + */ + private Map genericConfiguration; + + /** + * A <code>List</code> of <code>HardwareCryptoModule</code> objects for + * configuring hardware modules. + */ + private List hardwareCryptoModules; + + /** + * A <code>List</code> of <code>HardwareKey</code> objects containing the + * configuration data for hardware keys. + */ + private List hardwareKeyModules; + + /** + * A <code>List</code> of <code>SoftwareKey</code> objects containing the + * configuration data for software keys. + */ + private List softwareKeyModules; + + /** + * A <code>Map</code> which contains a KeyGroupId (a <code>String</code>) to + * KeyGroup mapping. + */ + private Map keyGroups; + + /** + * A <code>Map</code> which contains the <code>IssuerAndSerial</code> to + * <code>KeyGroup</code> mapping. + */ + private Map keyGroupMappings; + + /** The default chaining mode. */ + private String defaultChainingMode; + + /** + * A <code>Map</code> which contains the <code>IssuerAndSerial</code> to + * chaining mode (a <code>String</code>) mapping. + */ + private Map chainingModes; + + /** + * A <code>Map</code> which contains the CAIssuerDN (a <code>String</code>) + * to distribution points (a <code>Set</code> of + * <code>DistributionPoint</code>s) mapping. + */ + private Map crlDistributionPoints; + + /** The CRL archive duration. */ + private int cRLArchiveDuration; + + /** + * A <code>Map</code> which contains a mapping from + * CreateSignatureEnvironmentProfile Ids (<code>String</code>) to + * CreateSignatureEnvironmentProfile elements (an <code>Element</code>). + */ + private Map createSignatureEnvironmentProfiles; + + /** + * A <code>Map</code> which contains a mapping from + * CreateTransformsInfoProfile Ids (<code>String</code>) to + * CreateTransformsInfoProfile elements (an <code>Element</code>). + */ + private Map createTransformsInfoProfiles; + + /** + * A <code>Map</code> which contains a mapping from + * VerifyTransformsInfoProfile Ids (<code>String</code>) to + * VerifyTransformsInfoProfile elements (an <code>Element</code>). + */ + private Map verifyTransformsInfoProfiles; + + /** + * A <code>Map</code> which contains a mapping from + * SupplementProfile Ids (<code>String</code>) to SupplementProfile elements + * (an <code>Element</code>). + */ + private Map supplementProfiles; + + /** + * A <code>Map</code> which contains a TrustProfile Id (a <code>String</code> + * to trust profile (a <code>TrustProfile</code>) mapping. + */ + private Map trustProfiles; + + /** + * Return the single instance of configuration data. + * + * @return MOAConfigurationProvider The current configuration data. + * @throws ConfigurationException Failure to load the configuration data. + */ + public static synchronized ConfigurationProvider getInstance() + throws ConfigurationException { + + if (instance == null) { + reload(); + } + return instance; + } + + /** + * Reload the configuration data and set it if successful. + * + * @return MOAConfigurationProvider The loaded configuration data. + * @throws ConfigurationException Failure to load the configuration data. + */ + public static synchronized ConfigurationProvider reload() + throws ConfigurationException { + String fileName = System.getProperty(CONFIG_PROPERTY_NAME); + + if (fileName == null) { + // find out where we are running and use the configuration provided + // under WEB-INF/conf/moa-spss/MOA-SPSSConfiguration + URL url = ConfigurationProvider.class.getResource("/"); + fileName = + new File(url.getPath()).getParent() + + "/conf/moa-spss/MOA-SPSSConfiguration.xml"; + info("config.05", new Object[] { CONFIG_PROPERTY_NAME }); + } + + instance = new ConfigurationProvider(fileName); + return instance; + } + + /** + * Constructor for ConfigurationProvider. + * + * @param fileName The name of the configuration file. + * @throws ConfigurationException An error occurred loading the configuration. + */ + public ConfigurationProvider(String fileName) throws ConfigurationException { + load(fileName); + } + + /** + * Load the configuration data from XML file with the given name and build + * the internal data structures representing the MOA configuration. + * + * @param fileName The name of the XML file to load. + * @throws ConfigurationException The MOA configuration could not be + * read/built. + */ + private void load(String fileName) throws ConfigurationException { + FileInputStream stream = null; + File configFile; + File configRoot; + Element configElem; + ConfigurationPartsBuilder builder; + List allKeyModules; + + + // load the main config file + try { + configFile = new File(fileName); + configRoot = new File(configFile.getParent()); + info("config.21", new Object[] { configFile.getAbsoluteFile()}); + stream = new FileInputStream(fileName); + configElem = DOMUtils.parseXmlValidating(new FileInputStream(fileName)); + } catch (Throwable t) { + throw new ConfigurationException("config.10", null, t); + } + + // build the internal datastructures + try { + builder = new ConfigurationPartsBuilder(configElem); + digestMethodAlgorithmName = builder.getDigestMethodAlgorithmName(); + canonicalizationAlgorithmName = + builder.getCanonicalizationAlgorithmName(); + hardwareCryptoModules = builder.buildHardwareCryptoModules(); + hardwareKeyModules = + builder.buildHardwareKeyModules(Collections.EMPTY_LIST); + softwareKeyModules = + builder.buildSoftwareKeyModules(hardwareKeyModules, configRoot); + allKeyModules = new ArrayList(hardwareKeyModules); + allKeyModules.addAll(softwareKeyModules); + keyGroups = builder.buildKeyGroups(allKeyModules); + keyGroupMappings = + builder.buildKeyGroupMappings(keyGroups, ANONYMOUS_ISSUER_SERIAL); + defaultChainingMode = builder.getDefaultChainingMode(); + chainingModes = builder.buildChainingModes(); + crlDistributionPoints = builder.buildCRLDistributionPoints(); + cRLArchiveDuration = builder.getCRLArchiveDuration(); + genericConfiguration = builder.buildGenericConfiguration(); + absolutizeCertStoreRoot(configRoot); + createTransformsInfoProfiles = + builder.buildCreateTransformsInfoProfiles(configRoot); + createSignatureEnvironmentProfiles = + builder.buildCreateSignatureEnvironmentProfiles(configRoot); + verifyTransformsInfoProfiles = + builder.buildVerifyTransformsInfoProfiles(configRoot); + supplementProfiles = builder.buildSupplementProfiles(configRoot); + trustProfiles = builder.buildTrustProfiles(configRoot); + warnings = new ArrayList(builder.getWarnings()); + checkConsistency(); + } catch (Throwable t) { + throw new ConfigurationException("config.11", null, t); + } finally { + try { + if (stream != null) { + stream.close(); + } + } catch (IOException e) { + // don't complain about this + } + } + } + + /** + * Returns the warnings encountered during building the configuration. + * + * @return A <code>List</code> of <code>String</code>s, containing the + * warning messages. + */ + public List getWarnings() { + return warnings; + } + + /** + * Make the <code>DIRECTORY_CERTSTORE_PARAMETER_PROPERTY</code> generic + * configuration value an absolute file name. + * + * @param configRoot The root directory of the main configuration file. + */ + private void absolutizeCertStoreRoot(File configRoot) { + String certStoreRoot = + getGenericConfiguration(DIRECTORY_CERTSTORE_PARAMETER_PROPERTY); + + if (certStoreRoot != null) { + if (!new File(certStoreRoot).isAbsolute()) { + // make the cert store absolute + File absCertStore = new File(configRoot, certStoreRoot); + + setGenericConfiguration( + DIRECTORY_CERTSTORE_PARAMETER_PROPERTY, + absCertStore.getAbsolutePath()); + } + } else { + // no value given: set it to a reasonable (absolute) default + File absCertStore = new File(configRoot, "certstore"); + + setGenericConfiguration( + DIRECTORY_CERTSTORE_PARAMETER_PROPERTY, + absCertStore.getAbsolutePath()); + } + } + + /** + * Do some additional consistency checks on the configuration. + */ + private void checkConsistency() { + // check for valid DirectoryCertStoreParameters.RootDir + String certStoreRoot = + getGenericConfiguration(DIRECTORY_CERTSTORE_PARAMETER_PROPERTY); + + if (certStoreRoot != null) { + File certStore = new File(certStoreRoot); + + if (!certStore.exists() && !certStore.isDirectory()) { + boolean created = false; + + try { + created = certStore.mkdirs(); + } finally { + if (!created) { + warn( + "config.30", + new Object[] { DIRECTORY_CERTSTORE_PARAMETER_PROPERTY }); + } + } + } + } + + } + + /** + * Return the name of the digest algorithm used during signature creation. + * + * @return The digest method algorithm name, or an empty <code>String</code>, + * if none has been configured. + */ + public String getDigestMethodAlgorithmName() { + return digestMethodAlgorithmName; + } + + /** + * Return the name of the canonicalization algorithm used during signature + * creation. + * + * @return The canonicalization algorithm name, or an empty + * <code>String</code> if none has been configured. + */ + public String getCanonicalizationAlgorithmName() { + return canonicalizationAlgorithmName; + } + + /** + * Return the configured hardware crypto modules. + * + * @return A <code>List</code> of <code>HardwareCryptoModule</code> objects + * containing the hardware crypto module configurations. + */ + public List getHardwareCryptoModules() { + return hardwareCryptoModules; + } + + /** + * Return the hardware key modules configuration. + * + * @return A <code>List</code> of <code>HardwareKeyModule</code> objects + * containing the configuration of the hardware key modules. + */ + public List getHardwareKeyModules() { + return hardwareKeyModules; + } + + /** + * Return the software key module configuration. + * + * @return A <code>List</code> of <code>SoftwareKeyModule</code> objects + * containing the configuration of the software key modules. + */ + public List getSoftwareKeyModules() { + return softwareKeyModules; + } + + /** + * Return the key group mapping. + * + * @return A mapping from key group ID (a <code>String</code>) to + * <code>KeyGroup</code> mapping. + */ + public Map getKeyGroups() { + return keyGroups; + } + + /** + * Return the set of <code>KeyGroupEntry</code>s of a given key group, which a + * client (identified by an issuer/serial pair) may access. + * + * @param issuer The issuer of the client certificate. + * @param serial The serial number of the client certificate. + * @param keyGroupId The ID of the key group. + * @return A <code>Set</code> of all the <code>KeyGroupEntry</code>s in the + * given key group, if the user may access them. Returns <code>null</code>, if + * the user may not access the given key group or if the key group does not + * exist. + */ + public Set getKeyGroupEntries( + Principal issuer, + BigInteger serial, + String keyGroupId) { + + IssuerAndSerial issuerAndSerial; + Map mapping; + + if (issuer == null && serial == null) { + issuerAndSerial = ANONYMOUS_ISSUER_SERIAL; + } else { + issuerAndSerial = new IssuerAndSerial(issuer, serial); + } + + mapping = (Map) keyGroupMappings.get(issuerAndSerial); + if (mapping != null) { + KeyGroup keyGroup = (KeyGroup) mapping.get(keyGroupId); + + if (keyGroup != null) { + return keyGroup.getKeyGroupEntries(); + } + } + return null; + } + + /** + * Return the chaining mode for a given trust anchor. + * + * @param trustAnchor The trust anchor for which the chaining mode should be + * returned. + * @return The chaining mode for the given trust anchor. If the trust anchor + * has not been configured separately, the system default will be returned. + */ + public String getChainingMode(X509Certificate trustAnchor) { + Principal issuer = trustAnchor.getIssuerDN(); + BigInteger serial = trustAnchor.getSerialNumber(); + IssuerAndSerial issuerAndSerial = new IssuerAndSerial(issuer, serial); + + String mode = (String) chainingModes.get(issuerAndSerial); + return mode != null ? mode : defaultChainingMode; + } + + /** + * Return the CRL distribution points for a given CA. + * + * @param cert The certificate for which the CRL distribution points should be + * looked up. The issuer information is used to perform the lookup. + * @return A <code>Set</code> of <code>DistributionPoint</code> objects. The + * set will be empty, if no distribution points have been configured for this + * certificate. + */ + public Set getCRLDP(X509Certificate cert) { + try { + RFC2253NameParser nameParser = + new RFC2253NameParser(cert.getIssuerDN().toString()); + String caIssuerDN = nameParser.parse().getName(); + Set dps = (Set) crlDistributionPoints.get(caIssuerDN); + + if (dps == null) { + return Collections.EMPTY_SET; + } + return dps; + } catch (RFC2253NameParserException e) { + return Collections.EMPTY_SET; + } + } + + /** + * Return the CRL archive duration. + * + * @return The duration of how long to keep CRL archive entries (measured in + * days). + */ + public int getCRLArchiveDuration() { + return cRLArchiveDuration; + } + + /** + * Sets a generic configuration value. + * + * Existing values are overridden. + * + * @param name The name of the generic configuration. + * @param value The new value of the generic configuration. + */ + private void setGenericConfiguration(String name, String value) { + genericConfiguration.put(name, value); + } + + /** + * Return the value of a generic configuration. + * + * @param name The name of the generic configuration. + * @return The value of the generic configuration with the given name, or + * <code>null</code>, if none can be found. + */ + public String getGenericConfiguration(String name) { + return (String) genericConfiguration.get(name); + } + + /** + * Return the value of a generic configuration, or a given default value. + * + * @param name The name of the generic configuration. + * @param defaultValue A default value to be returned in case that the generic + * configuration with the given name does not exist. + * @return The value of the generic configuration with the given name, or the + * <code>defaultValue</code>, if none can be found. + */ + public String getGenericConfiguration(String name, String defaultValue) { + String value = (String) genericConfiguration.get(name); + return value != null ? value : defaultValue; + } + + /** + * Return a <code>CreateTransformsInfoProfile</code> with the given ID. + * + * @param id The <code>CreateTransformsInfoProfile</code> ID. + * @return The <code>CreateTransformsInfoProfile</code> with the given + * ID or <code>null</code>, if none exists. + */ + public Element getCreateTransformsInfoProfile(String id) { + return (Element) createTransformsInfoProfiles.get(id); + } + + /** + * Return a <code>CreateSignatureEnvironmentProfile</code> with the given ID. + * + * @param id The <code>CreateSignatureEnvironmentProfile</code> ID. + * @return The <code>CreateSignatureEnvironmentProfile</code> with the given + * ID or <code>null</code>, if none exists. + */ + public Element getCreateSignatureEnvironmentProfile(String id) { + return (Element) createSignatureEnvironmentProfiles.get(id); + } + + /** + * Return a <code>VerifyTransformsInfoProfile</code> with the given ID. + * + * @param id The <code>VerifyTransformsInfoProfile</code> ID. + * @return The <code>VerifyTransformsInfoProfile</code> with the given ID or + * <code>null</code>, if none exists. + */ + public Element getVerifyTransformsInfoProfile(String id) { + return (Element) verifyTransformsInfoProfiles.get(id); + } + + /** + * Return a <code>SupplementProfile</code> with the given ID. + * + * @param id The <code>SupplementProfile</code> ID. + * @return The <code>SupplementProfile</code> with the given ID or + * <code>null</code>, if none exists. + */ + public Element getSupplementProfile(String id) { + return (Element) supplementProfiles.get(id); + } + + /** + * Return a <code>TrustProfile</code> with the given ID. + * + * @param id The <code>TrustProfile</code> ID. + * @return The <code>TrustProfile</code> with the given ID or + * <code>null</code>, if none exists. + */ + public TrustProfile getTrustProfile(String id) { + return (TrustProfile) trustProfiles.get(id); + } + + /** + * Log a warning. + * + * @param messageId The message ID. + * @param parameters Additional parameters for the message. + * @see at.gv.egovernment.moa.spss.server.util.MessageProvider + */ + private static void info(String messageId, Object[] parameters) { + MessageProvider msg = MessageProvider.getInstance(); + Logger.info(new LogMsg(msg.getMessage(messageId, parameters))); + } + + /** + * Log a warning. + * + * @param messageId The message ID. + * @param args Additional parameters for the message. + * @see at.gv.egovernment.moa.spss.server.util.MessageProvider + */ + private void warn(String messageId, Object[] args) { + MessageProvider msg = MessageProvider.getInstance(); + String txt = msg.getMessage(messageId, args); + + Logger.warn(new LogMsg(txt)); + warnings.add(txt); + } + +}
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/DistributionPoint.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/DistributionPoint.java new file mode 100644 index 000000000..ce9588c87 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/DistributionPoint.java @@ -0,0 +1,134 @@ +package at.gv.egovernment.moa.spss.server.config; + +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; + +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A class containing information about a CRL distribution point. + * + * @author Sven Aigner + * @author Patrick Peck + * @version $Id$ + */ +public class DistributionPoint { + + private static Map RC_MAPPING = new HashMap(); + + static { + + // create the mapping between reason code strings and their integer values + RC_MAPPING.put( + "unused", + new Integer(iaik.asn1.structures.DistributionPoint.unused)); + RC_MAPPING.put( + "keyCompromise", + new Integer(iaik.asn1.structures.DistributionPoint.keyCompromise)); + RC_MAPPING.put( + "cACompromise", + new Integer(iaik.asn1.structures.DistributionPoint.cACompromise)); + RC_MAPPING.put( + "affiliationChanged", + new Integer(iaik.asn1.structures.DistributionPoint.affiliationChanged)); + RC_MAPPING.put( + "superseded", + new Integer(iaik.asn1.structures.DistributionPoint.superseded)); + RC_MAPPING.put( + "cessationOfOperation", + new Integer(iaik.asn1.structures.DistributionPoint.cessationOfOperation)); + RC_MAPPING.put( + "certificateHold", + new Integer(iaik.asn1.structures.DistributionPoint.certificateHold)); + RC_MAPPING.put( + "privilegeWithdrawn", + new Integer(iaik.asn1.structures.DistributionPoint.privilegeWithdrawn)); + RC_MAPPING.put( + "aACompromise", + new Integer(iaik.asn1.structures.DistributionPoint.aACompromise)); + } + + /** The distribution point URI. */ + private String uri; + /** The reason codes applicable for the distribution point. */ + private int reasonCodes; + + /** + * Create a <code>DistributionPoint</code> with a URI and a list of reason + * codes. + * + * @param uri The URI of the distribution point. + * @param reasonCodeStr A list of reason codes (a space-separated + * enumeration). + */ + public DistributionPoint(String uri, String reasonCodeStr) { + this.uri = uri; + this.reasonCodes = extractReasonCodes(reasonCodeStr); + } + + /** + * Convert a list of reason codes provided as a <code>String</code> to a + * binary representation. + * + * @param reasonCodeStr A <code>String</code> containing a blank-separated, + * textual representation of reason codes. + * @return int A binary representation of reason codes. + * @see iaik.asn1.structures.DistributionPoint + */ + private int extractReasonCodes(String reasonCodeStr) { + int codes = 0; + StringTokenizer tokenizer = new StringTokenizer(reasonCodeStr); + String token; + Integer reasonCode; + + while (tokenizer.hasMoreTokens()) { + token = tokenizer.nextToken(); + reasonCode = (Integer) RC_MAPPING.get(token); + if (reasonCode != null) { + codes |= reasonCode.intValue(); + } else { + MessageProvider msg = MessageProvider.getInstance(); + Logger.warn( + new LogMsg(msg.getMessage("config.07", new Object[] { token }))); + } + } + + return codes; + } + + /** + * Return the URI of the distribution point. + * + * @return The URI of the distribution point. + */ + public String getUri() { + return uri; + } + + /** + * Return a binary representation of the reason codes of this distribution + * point. + * + * @return The binary representation of the reason codes. + */ + public int getReasonCodes() { + return reasonCodes; + } + + /** + * Return a <code>String</code> representation of this distribution point. + * + * @return The <code>String</code> representation of this distribution point. + * @see java.lang.Object#toString() + */ + public String toString() { + return "(DistributionPoint - " + + ("URI<" + getUri()) + + ("> REASONCODES<" + getReasonCodes() + ">)"); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareCryptoModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareCryptoModule.java new file mode 100644 index 000000000..62e8d63a6 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareCryptoModule.java @@ -0,0 +1,60 @@ +package at.gv.egovernment.moa.spss.server.config; + +/** + * Contains configuration data for a hardware crypto module. + * + * @author Patrick Peck + * @version $Id$ + */ +public class HardwareCryptoModule { + /** The name of the module. */ + private String name; + /** The slod ID of the module. */ + private String slotID; + /** The user PIN of the module. */ + private String userPIN; + + /** + * Create a new <code>HardwareCryptoModule</code>. + * + * @param name The name of this <code>HardwareCryptoModule</code>. + * @param slotID The slot ID of this <code>HardwareCryptoModule</code>. + * @param userPIN The user PIN to access this + * <code>HardwareCryptoModule</code>. + */ + public HardwareCryptoModule(String name, String slotID, String userPIN) { + this.name = name; + this.slotID = slotID; + this.userPIN = userPIN; + } + + /** + * Returns the name of this <code>HardwareCryptoModule</code>. + * + * @return The name of this <code>HardwareCryptoModule</code>. + */ + public String getName() { + return name; + } + + /** + * Returns the slot ID of this <code>HardwareCryptoModule</code>. + * + * @return The slot ID. + */ + public String getSlotID() { + return slotID; + } + + + /** + * Returns the user PIN of this <code>HardwareCryptoModule</code>. + * + * @return The user PIN used to access the module. + */ + public String getUserPIN() { + return userPIN; + } + + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareKeyModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareKeyModule.java new file mode 100644 index 000000000..622c8d110 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareKeyModule.java @@ -0,0 +1,59 @@ +package at.gv.egovernment.moa.spss.server.config; + +/** + * A class that contains information about a hardware key module. + * + * @author Patrick Peck + * @version $Id$ + */ +public class HardwareKeyModule extends KeyModule { + /** The name of the module. */ + private String name; + /** The slod ID of the module. */ + private String slotID; + /** The user PIN of the module. */ + private String userPIN; + + /** + * Create a new <code>HardwareKey</code>. + * + * @param id The key module ID. + * @param name The name of the key. + * @param slotID The slot ID of the key within the hardware module. May be + * <code>null</code>. + * @param userPIN The user PIN to access the key. + */ + public HardwareKeyModule(String id, String name, String slotID, String userPIN) { + super(id); + this.name = name; + this.slotID = slotID; + this.userPIN = userPIN; + } + + /** + * Return the name of this <code>HardwareKey</code>. + * + * @return The name of this <code>HardwareKey</code>. + */ + public String getName() { + return name; + } + + /** + * Return the slot ID of this <code>HardwareKey</code>. + * + * @return The slot ID of this <code>HardwareKey</code>. + */ + public String getSlotID() { + return slotID; + } + + /** + * Return the user PIN to access this <code>HardwareKey</code>. + * + * @return The user PIN to access this <code>HardwareKey</code>. + */ + public String getUserPIN() { + return userPIN; + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/IssuerAndSerial.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/IssuerAndSerial.java new file mode 100644 index 000000000..9d9262785 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/IssuerAndSerial.java @@ -0,0 +1,115 @@ +package at.gv.egovernment.moa.spss.server.config; + +import java.math.BigInteger; +import java.security.Principal; + +import iaik.asn1.structures.Name; +import iaik.utils.RFC2253NameParser; +import iaik.utils.RFC2253NameParserException; + +/** + * A class containing the issuer and serial number of a certificate, which can + * be used to uniquely identify the certificate. + * + * The issuer is contained as an RFC2253 encoded <code>String</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class IssuerAndSerial { + + /** The issuer distinguished name. */ + private String issuerDN; + /** The certificate serial number. */ + private BigInteger serial; + + /** + * Create an <code>IssuerAndSerial</code> object. + * + * The name of the issuer is converted to RFC2253. If it cannot be parsed, the + * DN contained in the <code>issuer</code> is set. + * + * @param issuer The isser of a certificate. + * @param serial The serial number of the certificate. + */ + public IssuerAndSerial(Principal issuer, BigInteger serial) { + RFC2253NameParser parser = new RFC2253NameParser(issuer.getName()); + + try { + this.issuerDN = ((Name) parser.parse()).getRFC2253String(); + } catch (RFC2253NameParserException e) { + this.issuerDN = issuer.getName(); + } + this.serial = serial; + } + + /** + * Create an <code>IssuerAndSerial</code> object. + * + * @param issuerDN The issuer distinguished name. Should be an RFC2253 name. + * @param serial The serial number of the certificate. + */ + public IssuerAndSerial(String issuerDN, BigInteger serial) { + this.issuerDN = issuerDN; + this.serial = serial; + } + + /** + * Return the issuer DN in RFC2253 format. + * + * @return The issuer part of this object. + */ + public String getIssuerDN() { + return issuerDN; + } + + /** + * Return the serial number. + * + * @return The serial number of this object. + */ + public BigInteger getSerial() { + return serial; + } + + /** + * Compare this <code>IssuerAndSerial</code> to another object. + * + * @param other The object to compare this <code>IssuerAndSerial</code> to. + * @return <code>true</code>, if <code>other</code> is an + * <code>IssuerAndSerial</code> object and the <code>issuer</code> and + * <code>serial</code> fields are both equal. <code>false</code> otherwise. + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object other) { + if (other instanceof IssuerAndSerial) { + IssuerAndSerial ias = (IssuerAndSerial) other; + return getIssuerDN().equals(ias.getIssuerDN()) + && getSerial().equals(ias.getSerial()); + } + return false; + } + + /** + * Return the hash code of this <code>IssuerAndSerial</code>. + * + * @return The hash code of this <code>IssuerAndSerial</code>. + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return issuerDN.hashCode() ^ serial.hashCode(); + } + + /** + * Return a <code>String</code> representation of this + * <code>IssuerAndSerial</code> object. + * + * @return The <code>String</code> representation. + * @see java.lang.Object#toString() + */ + public String toString() { + return ("(IssuerAndSerial - Issuer<" + getIssuerDN()) + + ("> Serial<" + serial.toString() + ">)"); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroup.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroup.java new file mode 100644 index 000000000..5fd108e1a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroup.java @@ -0,0 +1,69 @@ +package at.gv.egovernment.moa.spss.server.config; + +import java.util.Iterator; +import java.util.Set; + +/** + * A collection of <code>KeyGroupEntry</code>s with its own ID. + * + * @author Sven Aigner + * @author Patrick Peck + * @version $Id$ + */ +public class KeyGroup { + + /** The keys belonging to this key group. */ + private Set keyGroupEntries; + /** The key group ID. */ + private String id; + + /** + * Create a <code>KeyGroup</code>. + * + * @param id The ID of this <code>KeyGroup</code>. + * @param keyGroupEntries The keys belonging to this <code>KeyGroup</code>. + */ + public KeyGroup(String id, Set keyGroupEntries) { + this.id = id; + this.keyGroupEntries = keyGroupEntries; + } + + /** + * Return the <code>KeyEntry</code>s contained in this <code>KeyGroup</code>. + * + * @return The <code>KeyEntry</code>s contained in this <code>KeyGroup</code>. + */ + public Set getKeyGroupEntries() { + return keyGroupEntries; + } + + /** + * Return the ID of this <code>KeyGroup</code>. + * + * @return The <code>KeyGroup</code> ID. + */ + public String getId() { + return id; + } + + /** + * Return a <code>String</code> representation of this <code>KeyGroup</code>. + * + * @return The <code>String</code> representation. + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + Iterator i; + + if (getKeyGroupEntries() != null) { + i = getKeyGroupEntries().iterator(); + + while (i.hasNext()) { + sb.append(" " + i.next()); + } + } + return "(KeyGroup - ID:" + id + " " + sb.toString() + ")"; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroupEntry.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroupEntry.java new file mode 100644 index 000000000..2e39d6aa3 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroupEntry.java @@ -0,0 +1,106 @@ +package at.gv.egovernment.moa.spss.server.config; + +import java.math.BigInteger; + +/** + * A class containing information about an entry in a key group. + * + * @author Patrick Peck + * @version $Id$ + */ +public class KeyGroupEntry { + /** The module ID of the key. */ + private String moduleID; + /** The issuer DN of the certificate identifying the key. */ + private String issuerDN; + /** The serial number of the certificate identifying the key. */ + private BigInteger serialNumber; + + /** + * Create a new <code>KeyGroupEntry</code>. + * + * @param moduleID The key module ID to which this entry belongs to. + * @param issuerAndSerial The issuer and serial number which uniquely + * identifies a certificate within the key module. + */ + public KeyGroupEntry(String moduleID, IssuerAndSerial issuerAndSerial) { + this.moduleID = moduleID; + this.issuerDN = issuerAndSerial.getIssuerDN(); + this.serialNumber = issuerAndSerial.getSerial(); + } + + /** + * Create a new <code>KeyGroupEntry</code>. + * + * @param moduleID The key module ID to which this entry belongs to. + * @param issuerDN The isser DN of the certificate within the key module. + * @param serialNumber The serial number of the certificate within the key + * module. + */ + public KeyGroupEntry( + String moduleID, + String issuerDN, + BigInteger serialNumber) { + this.moduleID = moduleID; + this.issuerDN = issuerDN; + this.serialNumber = serialNumber; + } + + /** + * Return the key module ID to which this <code>KeyGroupEntry</code> belongs + * to. + * + * @return The key module ID. + */ + public String getModuleID() { + return moduleID; + } + + /** + * Return the issuer DN of this <code>KeyGroupEntry</code> for identifying the + * certificate within the key module. + * + * @return The issuer DN of the certificate. + */ + public String getIssuerDN() { + return issuerDN; + } + + /** + * Return the serial number of this <code>KeyGroupEntry</code> for identifying + * the certificate within the key module. + * + * @return The serial number of the certificate. + */ + public BigInteger getSerialNumber() { + return serialNumber; + } + + /** + * Compare this <code>KeyGroupEntry</code> to another. + * + * @param other The <code>KeyGroupEntry</code> to compare to. + * @return <code>true</code>, if module ID, isser DN and serial number of + * <code>other</code> match the ones contained in this object, otherwise + * <code>false</code>. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof KeyGroupEntry) { + KeyGroupEntry entry = (KeyGroupEntry) other; + return getModuleID().equals(entry.getModuleID()) + && getIssuerDN().equals(entry.getIssuerDN()) + && getSerialNumber().equals(entry.getSerialNumber()); + } + return false; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getModuleID().hashCode() + ^ getIssuerDN().hashCode() + ^ getSerialNumber().hashCode(); + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyModule.java new file mode 100644 index 000000000..412516d82 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyModule.java @@ -0,0 +1,41 @@ +package at.gv.egovernment.moa.spss.server.config; + +/** + * A class that contains information about a key module. + * + * @author Patrick Peck + * @version $Id$ + */ +public class KeyModule { + + /** The key module ID. */ + private String id; + + /** + * Create a <code>Key</code> object. + * + * @param id The key module ID. + */ + public KeyModule(String id) { + this.id = id; + } + + /** + * Return the key ID. + * + * @return The key ID. + */ + public String getId() { + return id; + } + + /** + * Return a <code>String</code> representation of this <code>Key</code>. + * + * @return The <code>String</code> representation. + * @see java.lang.Object#toString() + */ + public String toString() { + return "(Key - Id<" + id + ">)"; + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/SoftwareKeyModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/SoftwareKeyModule.java new file mode 100644 index 000000000..479e98ca5 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/SoftwareKeyModule.java @@ -0,0 +1,48 @@ +package at.gv.egovernment.moa.spss.server.config; + +/** + * A class containing information about a software key, stored in PKCS12 format. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SoftwareKeyModule extends KeyModule { + /** The name of the file containing the keys. */ + private String fileName; + /** The password for accessing the file. */ + private String passWord; + + /** + * Create a new <code>SoftwareKey</code>. + * + * @param id The key ID. + * @param fileName The name of the PKCS12 keystore file containing the key. + * @param passWord The password to access the keystore file. + */ + public SoftwareKeyModule(String id, String fileName, String passWord) { + super(id); + this.fileName = fileName; + this.passWord = passWord; + } + + /** + * Return the name of the PKCS12 keystore file containing this + * <code>SoftwareKey</code>. + * + * @return The name of the PKCS12 keystore file. + */ + public String getFileName() { + return fileName; + } + + /** + * Return the password to access the keystore file. + * + * @return The password to access the keystore file. + */ + public String getPassWord() { + return passWord; + } + + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java new file mode 100644 index 000000000..6ba33be63 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java @@ -0,0 +1,43 @@ +package at.gv.egovernment.moa.spss.server.config; + +/** + * Information about a trust profile. + * + * @author Patrick Peck + * @version $Id$ + */ +public class TrustProfile { + /** The ID of the trust profile. */ + private String id; + /** The URI giving the location of the trust profile. */ + private String uri; + + /** + * Create a <code>TrustProfile</code>. + * + * @param id The ID of the <code>TrustProfile</code> to create. + * @param uri The URI of the <code>TrustProfile</code> to create. + */ + public TrustProfile(String id, String uri) { + this.id = id; + this.uri = uri; + } + + /** + * Return the ID of this <code>TrustProfile</code>. + * + * @return The <code>TrustProfile</code> ID. + */ + public String getId() { + return id; + } + + /** + * Return the URI of this <code>TrustProfile</code>. + * + * @return The URI of <code>TrustProfile</code>. + */ + public String getUri() { + return uri; + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/cmsverify/CMSSignatureVerificationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/cmsverify/CMSSignatureVerificationProfileImpl.java new file mode 100644 index 000000000..eaee58d3f --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/cmsverify/CMSSignatureVerificationProfileImpl.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.spss.server.iaik.cmsverify; + +import iaik.pki.PKIProfile; +import iaik.server.modules.cmsverify.CMSSignatureVerificationProfile; + +/** + * An implementation of the <code>CMSSignatureVerificationProfile</code> + * interface. + * + * @see iaik.server.modules.cmsverify.CMSSignatureVerificationProfile + * @author Patrick Peck + * @version $Id$ + */ +public class CMSSignatureVerificationProfileImpl + implements CMSSignatureVerificationProfile { + + /** The profile for validating the certificate. */ + private PKIProfile certificateValidationProfile; + + /** + * @see iaik.server.modules.cmsverify.CMSSignatureVerificationProfile#getCertificateValidationProfile() + */ + public PKIProfile getCertificateValidationProfile() { + return certificateValidationProfile; + } + + /** + * Sets the profile for validating the signer certificate. + * + * @param certificateValidationProfile The certificate validation profile to + * set. + */ + public void setCertificateValidationProfile(PKIProfile certificateValidationProfile) { + this.certificateValidationProfile = certificateValidationProfile; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractKeyModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractKeyModuleConfigurationImpl.java new file mode 100644 index 000000000..713891714 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractKeyModuleConfigurationImpl.java @@ -0,0 +1,36 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.server.modules.keys.KeyModuleConfiguration; + +/** + * Base implementation class for the <code>KeyModuleConfiguration</code> + * interface and the interfaces derived from it. + * + * @see iaik.server.modules.keys.KeyModuleConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public abstract class AbstractKeyModuleConfigurationImpl + implements KeyModuleConfiguration { + + /** The module ID. */ + private String moduleID; + + /** + * Creata new <code>AbstractKeyModuleConfigurationImpl</code>. + * + * @param moduleID The key module ID of this + * <code>KeyModuleConfiguration</code>. + */ + public AbstractKeyModuleConfigurationImpl(String moduleID) { + this.moduleID = moduleID; + } + + /** + * @see iaik.server.modules.keys.KeyModuleConfiguration#getModuleID() + */ + public String getModuleID() { + return moduleID; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractObservableConfiguration.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractObservableConfiguration.java new file mode 100644 index 000000000..ac4286701 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractObservableConfiguration.java @@ -0,0 +1,48 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import iaik.servertools.observer.NotificationData; +import iaik.servertools.observer.Observable; +import iaik.servertools.observer.Observer; + +/** + * A base class for observable configuration data. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class AbstractObservableConfiguration implements Observable { + + /** The observers registered with this <code>Observable</code>. */ + private List observers = new ArrayList(); + + /** + * @see iaik.utils.observer.Observable#addObserver(iaik.utils.observer.Observer) + */ + public void addObserver(Observer observer) { + observers.add(observer); + } + + /** + * @see iaik.utils.observer.Observable#removeObserver(iaik.utils.observer.Observer) + */ + public boolean removeObserver(Observer observer) { + return observers.remove(observer); + } + + /** + * @see iaik.utils.observer.Observable#notify(iaik.utils.observer.NotificationData) + */ + public void notify(NotificationData data) { + Iterator iter = observers.iterator(); + + for (iter = observers.iterator(); iter.hasNext();) { + Observer observer = (Observer) iter.next(); + observer.notify(data); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ArchiveConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ArchiveConfigurationImpl.java new file mode 100644 index 000000000..22d798bc3 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ArchiveConfigurationImpl.java @@ -0,0 +1,62 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.pki.store.revocation.archive.ArchiveConfiguration; +import iaik.pki.store.revocation.archive.ArchiveParameter; +import iaik.pki.store.revocation.archive.ArchiveTypes; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * An implementation of the <code>ArchiveConfiguration</code> interface + * using configuration data provided by the MOA configuration file. + * + * @see iaik.pki.store.revocation.archive.ArchiveConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public class ArchiveConfigurationImpl + extends AbstractObservableConfiguration + implements ArchiveConfiguration { + + /** The configuration parameters of the archive. */ + private ArchiveParameter archiveParameters; + + /** + * Create a new <code>ArchiveConfigurationImpl</code>. + * + * @param config The MOA configuration from which the configuration data is + * being read. + */ + public ArchiveConfigurationImpl(ConfigurationProvider config) { + String jdbcUrl = + config.getGenericConfiguration( + ConfigurationProvider.DATABASE_ARCHIVE_PARAMETER_PROPERTY); + + if (jdbcUrl != null) { + this.archiveParameters = new DataBaseArchiveParameterImpl(jdbcUrl); + } + } + + /** + * Return the type of archive. + * + * This will always return <code>ArchiveTypes.DATABASE</code>. + * @return <code>ArchiveTypes.DATABASE</code>. + * @see iaik.pki.store.revocation.archive.ArchiveConfiguration#getType() + */ + public String getType() { + return ArchiveTypes.DATABASE; + } + + /** + * Return the <code>ArchiveParameters</code> describing this + * <code>ArchiveConfiguration</code>. + * + * @return The archive parameters. + * @see iaik.pki.store.revocation.archive.ArchiveConfiguration#getArchiveParameters() + */ + public ArchiveParameter getArchiveParameters() { + return archiveParameters; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CRLDistributionPointAdapter.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CRLDistributionPointAdapter.java new file mode 100644 index 000000000..1c2df80a5 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CRLDistributionPointAdapter.java @@ -0,0 +1,54 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.pki.revocation.CRLDistributionPoint; +import iaik.pki.revocation.RevocationSourceTypes; + +import at.gv.egovernment.moa.spss.server.config.DistributionPoint; + +/** + * A class that wraps an + * at.gv.egovernment.moa.spss.server.config.DistributionPoint as a + * iaik.pki.revocation.CRLDistributionPoint. + * + * @see iaik.pki.revocation.CRLDistributionPoint + * @author Patrick Peck + * @version $Id$ + */ +public class CRLDistributionPointAdapter implements CRLDistributionPoint { + + /** The wrapped <code>DistributionPoint</code>. */ + private DistributionPoint distributionPoint; + + /** + * Create a new <code>CRLDistributionPointAdapter</code>. + * + * @param distributionPoint The <code>DistributionPoint</code> to wrap. It + * contains the data configured in the MOA configuration. + */ + public CRLDistributionPointAdapter(DistributionPoint distributionPoint) { + this.distributionPoint = distributionPoint; + } + + /** + * @see iaik.pki.revocation.CRLDistributionPoint#getReasonCodes() + */ + public int getReasonCodes() { + return distributionPoint.getReasonCodes(); + } + + /** + * @return <code>RevocationSourceTypes.CRL</code> + * @see iaik.pki.revocation.DistributionPoint#getType() + */ + public String getType() { + return RevocationSourceTypes.CRL; + } + + /** + * @see iaik.pki.revocation.DistributionPoint#getUri() + */ + public String getUri() { + return distributionPoint.getUri(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CertStoreConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CertStoreConfigurationImpl.java new file mode 100644 index 000000000..c9be3fc2b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CertStoreConfigurationImpl.java @@ -0,0 +1,54 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.pki.store.certstore.CertStoreConfiguration; +import iaik.pki.store.certstore.CertStoreParameters; +import iaik.pki.store.certstore.directory.DirectoryCertStoreParameters; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * An implementation of the <code>CertStoreConfiguration</code> interface based + * on MOA configuration data. + * + * @see iaik.pki.store.certstore.CertStoreConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public class CertStoreConfigurationImpl + extends AbstractObservableConfiguration + implements CertStoreConfiguration { + + /** The configuration parameters of the <code>CertStore</code>. */ + private CertStoreParameters[] parameters; + + /** + * Create a new <code>CertStoreConfigurationImpl</code>. + * + * @param config The MOA configuration from which the configuration data is + * being read. + */ + public CertStoreConfigurationImpl(ConfigurationProvider config) { + String certStoreRoot = + config.getGenericConfiguration( + ConfigurationProvider.DIRECTORY_CERTSTORE_PARAMETER_PROPERTY, + "certstore"); + + if (certStoreRoot != null) { + DirectoryCertStoreParameters dirParameters = + new DirectoryCertStoreParametersImpl( + "MOA Directory CertStore", + certStoreRoot, + true, + false); + parameters = new CertStoreParameters[] { dirParameters }; + } + } + + /** + * @see iaik.pki.store.certstore.CertStoreConfiguration#getParameters() + */ + public CertStoreParameters[] getParameters() { + return parameters; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ConfigurationDataImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ConfigurationDataImpl.java new file mode 100644 index 000000000..7aa4cbe4b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ConfigurationDataImpl.java @@ -0,0 +1,121 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import iaik.logging.LoggerConfig; +import iaik.pki.PKIConfiguration; +import iaik.server.ConfigurationData; + +import at.gv.egovernment.moa.spss.server.config.HardwareCryptoModule; +import at.gv.egovernment.moa.spss.server.config.HardwareKeyModule; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.config.SoftwareKeyModule; + +/** + * An implementation of the <code>ConfigurationData</code> interface using + * MOA configuration data. + * + * @see iaik.server.ConfigurationData + * @author Patrick Peck + * @version $Id$ + */ +public class ConfigurationDataImpl implements ConfigurationData { + /** PKI configuration data. */ + private PKIConfiguration pkiConfiguration; + /** Crypto modules configuration data. */ + private List cryptoModuleConfigurations; + /** Key modules configuration data. */ + private List keyModuleConfigurations; + /** Logging configuration data. */ + private LoggerConfig loggerConfig; + + /** + * Create a new <code>ConfigurationDataImpl</code>. + * + * @param config The underlying MOA configuration data. + */ + public ConfigurationDataImpl(ConfigurationProvider config) { + this.pkiConfiguration = new PKIConfigurationImpl(config); + this.cryptoModuleConfigurations = buildCryptoModuleConfigurations(config); + this.keyModuleConfigurations = buildKeyModuleConfigurations(config); + this.loggerConfig = new LoggerConfigImpl(); + } + + /** + * Build the list of <code>CryptoModuleConfiguration</code>s. + * + * @param config The underlying MOA configuration data. + * @return The list of <code>CryptoModuleConfiguration</code>s configured in + * the MOA configuration. + */ + private List buildCryptoModuleConfigurations(ConfigurationProvider config) { + List modules = new ArrayList(); + Iterator iter = config.getHardwareCryptoModules().iterator(); + + while (iter.hasNext()) { + HardwareCryptoModule module = (HardwareCryptoModule) iter.next(); + modules.add(new HardwareCryptoModuleConfigurationImpl(module)); + } + + return modules; + } + + /** + * Build the list of <code>KeyModuleConfiguration</code>s. + * + * @param config The underlying MOA configuration data. + * @return The list of <code>KeyModuleConfiguration</code>s configured in the + * MOA configuration. + */ + private List buildKeyModuleConfigurations(ConfigurationProvider config) { + List keys = new ArrayList(); + Iterator iter; + + // add the hardware keys + iter = config.getHardwareKeyModules().iterator(); + while (iter.hasNext()) { + HardwareKeyModule key = (HardwareKeyModule) iter.next(); + keys.add(new HardwareKeyModuleConfigurationImpl(key)); + } + + // add the software keys + iter = config.getSoftwareKeyModules().iterator(); + while (iter.hasNext()) { + SoftwareKeyModule key = (SoftwareKeyModule) iter.next(); + keys.add(new SoftwareKeyModuleConfigurationImpl(key)); + } + + return keys; + } + + /** + * @see iaik.server.ConfigurationData#getPKIConfiguration() + */ + public PKIConfiguration getPKIConfiguration() { + return pkiConfiguration; + } + + /** + * @see iaik.server.ConfigurationData#getCryptoModuleConfigurations() + */ + public List getCryptoModuleConfigurations() { + return cryptoModuleConfigurations; + } + + /** + * @see iaik.server.ConfigurationData#getKeyModuleConfigurations() + */ + public List getKeyModuleConfigurations() { + return keyModuleConfigurations; + } + + /** + * @see iaik.server.ConfigurationData#getLoggerConfig() + */ + public LoggerConfig getLoggerConfig() { + return loggerConfig; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DataBaseArchiveParameterImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DataBaseArchiveParameterImpl.java new file mode 100644 index 000000000..d67523944 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DataBaseArchiveParameterImpl.java @@ -0,0 +1,33 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.pki.store.revocation.archive.db.DataBaseArchiveParameter; + +/** + * An implementation of the <code>DataBaseArchiveParameter</code> interface. + * + * @see iaik.pki.store.revocation.archive.db.DataBaseArchiveParameter + * @author Patrick Peck + * @version $Id$ + */ +public class DataBaseArchiveParameterImpl implements DataBaseArchiveParameter { + + /** The JDBC URL for accessing the archive. */ + private String jDBCUrl; + + /** + * Create a new <code>DataBaseArchiveParameterImpl</code>. + * + * @param jDBCUrl The JDBC URL of the archive. + */ + public DataBaseArchiveParameterImpl(String jDBCUrl) { + this.jDBCUrl = jDBCUrl; + } + + /** + * @see iaik.pki.store.revocation.archive.db.DataBaseArchiveParameter#getJDBCUrl() + */ + public String getJDBCUrl() { + return jDBCUrl; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DirectoryCertStoreParametersImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DirectoryCertStoreParametersImpl.java new file mode 100644 index 000000000..2b00d6766 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DirectoryCertStoreParametersImpl.java @@ -0,0 +1,81 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.pki.store.certstore.CertStoreTypes; +import iaik.pki.store.certstore.directory.DirectoryCertStoreParameters; + +/** + * An implementation of the <code>DirectoryCertStoreParameters</code> interface. + * + * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters + * @author Patrick Peck + * @version $Id$ + */ +public class DirectoryCertStoreParametersImpl + implements DirectoryCertStoreParameters { + + /** The root directory of the <code>CertStore</code>. */ + private String rootDirectory; + /** Whether a new directory may be created. */ + private boolean createNew; + /** The <code>CertStore</code> ID. */ + private String id; + /** Whether the <code>CertStore</code> is read-only. */ + private boolean readOnly; + + /** + * Create a new <code>DirectoryCertStoreParameterImpl</code>. + * + * @param id The <code>CertStore</code> ID. + * @param rootDirectory The root directory of the <code>CertStore</code>. + * @param createNew Whether a new directory may be created. + * @param readOnly Whether the <code>CertStore</code> is read-only. + */ + public DirectoryCertStoreParametersImpl( + String id, + String rootDirectory, + boolean createNew, + boolean readOnly) { + + this.id = id; + this.rootDirectory = rootDirectory; + this.createNew = createNew; + this.readOnly = readOnly; + } + + /** + * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#getRootDirectory() + */ + public String getRootDirectory() { + return rootDirectory; + } + + /** + * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#createNew() + */ + public boolean createNew() { + return createNew; + } + + /** + * @see iaik.pki.store.certstore.CertStoreParameters#getId() + */ + public String getId() { + return id; + } + + /** + * @see iaik.pki.store.certstore.CertStoreParameters#isReadOnly() + */ + public boolean isReadOnly() { + return readOnly; + } + + /** + * @return <code>CertStoreTypes.DIRECTORY</code> + * @see iaik.pki.store.certstore.CertStoreParameters#getType() + */ + public String getType() { + return CertStoreTypes.DIRECTORY; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareCryptoModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareCryptoModuleConfigurationImpl.java new file mode 100644 index 000000000..3c8f4c002 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareCryptoModuleConfigurationImpl.java @@ -0,0 +1,51 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.server.modules.crypto.HardwareCryptoModuleConfiguration; + +import at.gv.egovernment.moa.spss.server.config.HardwareCryptoModule; + +/** + * An implementation of the <code>HardwareCryptoModuleConfiguration</code> + * wrapping a <code>HardwareCryptoModule</code> from the MOA configuration. + * + * @author Patrick Peck + * @version $Id$ + */ +public class HardwareCryptoModuleConfigurationImpl + implements HardwareCryptoModuleConfiguration { + + /** The wrapped <code>HardwareCryptoModule</code>. */ + private HardwareCryptoModule module; + + /** + * Create a new <code>HardwareCryptoModuleConfigurationImpl</code>. + * + * @param module The <code>HardwareCryptoModule</code> from the underlying MOA + * configuration. + */ + public HardwareCryptoModuleConfigurationImpl(HardwareCryptoModule module) { + this.module = module; + } + + /** + * @see iaik.server.modules.crypto.HardwareCryptoModuleConfiguration#getModuleName() + */ + public String getModuleName() { + return module.getName(); + } + + /** + * @see iaik.server.modules.crypto.HardwareCryptoModuleConfiguration#getSlotID() + */ + public String getSlotID() { + return module.getSlotID(); + } + + /** + * @see iaik.server.modules.crypto.HardwareCryptoModuleConfiguration#getUserPIN() + */ + public char[] getUserPIN() { + return module.getUserPIN().toCharArray(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareKeyModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareKeyModuleConfigurationImpl.java new file mode 100644 index 000000000..d905588c6 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareKeyModuleConfigurationImpl.java @@ -0,0 +1,55 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.server.modules.keys.HardwareKeyModuleConfiguration; + +import at.gv.egovernment.moa.spss.server.config.HardwareKeyModule; + +/** + * An implementation of the <code>HardwareKeyModuleConfiguration</code> + * interface wrapping a <code>HardwareKeyModule</code> from the MOA + * configuration. + * + * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public class HardwareKeyModuleConfigurationImpl + extends AbstractKeyModuleConfigurationImpl + implements HardwareKeyModuleConfiguration { + + /** The wrapped <code>HardwareKeyModule</code>. */ + private HardwareKeyModule keyModule; + + /** + * Create a new <code>HardwareKeyModuleConfigurationImpl</code>. + * + * @param keyModule The <code>HardwareKeyModule</code> from the underlying + * MOA configuration. + */ + public HardwareKeyModuleConfigurationImpl(HardwareKeyModule keyModule) { + super(keyModule.getId()); + this.keyModule = keyModule; + } + + /** + * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration#getModuleName() + */ + public String getModuleName() { + return keyModule.getName(); + } + + /** + * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration#getSlotID() + */ + public String getSlotID() { + return keyModule.getSlotID(); + } + + /** + * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration#getUserPIN() + */ + public char[] getUserPIN() { + return keyModule.getUserPIN().toCharArray(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/IaikConfigurator.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/IaikConfigurator.java new file mode 100644 index 000000000..8bd410ac7 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/IaikConfigurator.java @@ -0,0 +1,162 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import iaik.pki.store.truststore.TrustStoreFactory; +import iaik.server.ConfigurationData; +import iaik.server.Configurator; +import iaik.server.modules.keys.KeyEntryID; +import iaik.server.modules.keys.KeyModule; +import iaik.server.modules.keys.KeyModuleFactory; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.config.KeyGroup; +import at.gv.egovernment.moa.spss.server.config.KeyGroupEntry; +import at.gv.egovernment.moa.spss.server.logging.TransactionId; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A class responsible for configuring the IAIK MOA modules. + * + * @author Patrick Peck + * @version $Id$ + */ +public class IaikConfigurator { + + /** The warnings encountered during configuration. */ + private List warnings = new ArrayList(); + + /** + * Configure the IAIK MOA subsystem. + * + * @param moaConfig The underlying MOA configuration. + * @throws ConfigurationException An error occurred configuring the IAIK + * MOA subsystem. + */ + public void configure(ConfigurationProvider moaConfig) + throws ConfigurationException { + ConfigurationData configData = new ConfigurationDataImpl(moaConfig); + + warnings = new ArrayList(); + + try { + Configurator.init(configData, new TransactionId("IaikConfigurator")); + dumpKeyEntryIDs(); + checkKeyGroupConfig(moaConfig); + TrustStoreFactory.reset(); + } catch (iaik.server.ConfigurationException e) { + throw new ConfigurationException("config.08", null, e); + } catch (Throwable t) { + throw new ConfigurationException("config.08", null, t); + } + } + + /** + * Return the warnings encountered during configuration. + * + * @return The warnings. + */ + public List getWarnings() { + return warnings; + } + + /** + * Dump all <code>KeyEntryID</code>s contained in the configured + * <code>KeyModule</code>s to the log file. + */ + private void dumpKeyEntryIDs() { + MessageProvider msg = MessageProvider.getInstance(); + KeyModule module = KeyModuleFactory.getInstance(new TransactionId("dump")); + Set keyEntryIds = module.getPrivateKeyEntryIDs(); + Iterator iter; + + for (iter = keyEntryIds.iterator(); iter.hasNext();) { + KeyEntryID keyEntryId = (KeyEntryID) iter.next(); + Logger.info( + new LogMsg(msg.getMessage("config.19", new Object[] { keyEntryId }))); + } + } + + /** + * Check that each key group entry in each key group can be resolved to a + * KeyEntryID. + * + * Logs a warning for each key group entry that cannot be resolved. + * + * @param moaConfig The MOA configuration to check. + */ + private void checkKeyGroupConfig(ConfigurationProvider moaConfig) { + Map keyGroups = moaConfig.getKeyGroups(); + Iterator iter; + + for (iter = keyGroups.values().iterator(); iter.hasNext();) { + KeyGroup keyGroup = (KeyGroup) iter.next(); + Set keyGroupEntries = keyGroup.getKeyGroupEntries(); + Iterator kgIter; + + for (kgIter = keyGroupEntries.iterator(); kgIter.hasNext();) { + KeyGroupEntry entry = (KeyGroupEntry) kgIter.next(); + + if (!findKeyEntryID(entry)) { + warn( + "config.31", + new Object[] { + keyGroup.getId(), + entry.getModuleID(), + entry.getIssuerDN(), + entry.getSerialNumber()}); + } + } + } + } + + /** + * Find out that a certain KeyGroupEntry could be resolved to a KeyEntryID + * by the Configurator. + * + * @param keyGroupEntry The key group entry to find. + * @return <code>true</code>, if the <code>keyGroupEntry</code> could be + * resolved to a <code>KeyEntryID</code>; otherwise <code>false</code>. + */ + private boolean findKeyEntryID(KeyGroupEntry keyGroupEntry) { + KeyModule module = KeyModuleFactory.getInstance(new TransactionId("check")); + Set keyEntryIDs = module.getPrivateKeyEntryIDs(); + Iterator iter; + + for (iter = keyEntryIDs.iterator(); iter.hasNext();) { + KeyEntryID entry = (KeyEntryID) iter.next(); + + if (entry.getCertificateIssuer().equals(keyGroupEntry.getIssuerDN()) + && entry.getCertificateSerialNumber().equals( + keyGroupEntry.getSerialNumber()) + && entry.getModuleID().equals(keyGroupEntry.getModuleID())) { + return true; + } + } + + return false; + } + + /** + * Log a warning. + * + * @param messageId The message ID. + * @param args Additional parameters for the message. + * @see at.gv.egovernment.moa.spss.server.util.MessageProvider + */ + private void warn(String messageId, Object[] args) { + MessageProvider msg = MessageProvider.getInstance(); + String txt = msg.getMessage(messageId, args); + + Logger.warn(new LogMsg(txt)); + warnings.add(txt); + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/LoggerConfigImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/LoggerConfigImpl.java new file mode 100644 index 000000000..9679e8d18 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/LoggerConfigImpl.java @@ -0,0 +1,34 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import java.util.Properties; + +import iaik.logging.LogConfigurationException; +import iaik.logging.LoggerConfig; + +import at.gv.egovernment.moa.logging.LoggingContextManager; + +/** + * Default implementation of the <code>LoggerConfig</code> interface. + * + * @author Patrick Peck + * @version $Id$ + */ +public class LoggerConfigImpl implements LoggerConfig { + + /** The implementation of iaik.logging.LogFactory. */ + private static final String DEFAULT_IMPLEMENTATION = + "at.gv.egovernment.moa.spss.server.logging.IaikLogFactory"; + + public String getFactory() { + return DEFAULT_IMPLEMENTATION; + } + + public Properties getProperties() throws LogConfigurationException { + return new Properties(); + } + + public String getNodeId() { + return LoggingContextManager.getInstance().getLoggingContext().getNodeID(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/PKIConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/PKIConfigurationImpl.java new file mode 100644 index 000000000..0703cd326 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/PKIConfigurationImpl.java @@ -0,0 +1,85 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import iaik.pki.PKIConfiguration; +import iaik.pki.pathvalidation.ValidationConfiguration; +import iaik.pki.revocation.RevocationConfiguration; +import iaik.pki.store.certstore.CertStoreConfiguration; +import iaik.pki.store.revocation.archive.ArchiveConfiguration; + +import at.gv.egovernment.moa.util.BoolUtils; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * An implementation of the <code>PKIConfiguration</code> interface using data + * from the MOA configuration. + * + * @see iaik.pki.PKIConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public class PKIConfigurationImpl implements PKIConfiguration { + /** The <code>CertStore</code> configuration. */ + private CertStoreConfiguration certStoreConfiguration; + /** The revocation checking configuration. */ + private RevocationConfiguration revocationConfiguration; + /** The revocation archive configuration. */ + private ArchiveConfiguration archiveConfiguration; + /** The certificate validation configuration. */ + private ValidationConfiguration validationConfiguration; + + /** + * Create a new <code>PKIConfigurationImpl</code>. + * + * @param config The underlying MOA configuration which will be used to build + * the configuration data contained in this object. + */ + public PKIConfigurationImpl(ConfigurationProvider config) { + String archiveInfo; + + this.certStoreConfiguration = new CertStoreConfigurationImpl(config); + + this.revocationConfiguration = new RevocationConfigurationImpl(config); + + archiveInfo = + config.getGenericConfiguration( + ConfigurationProvider.ARCHIVE_REVOCATION_INFO_PROPERTY, + "false"); + if (archiveInfo != null && BoolUtils.valueOf(archiveInfo)) { + this.archiveConfiguration = new ArchiveConfigurationImpl(config); + } else { + this.archiveConfiguration = null; + } + + this.validationConfiguration = new ValidationConfigurationImpl(config); + } + + /** + * @see iaik.pki.PKIConfiguration#getCertStoreConfiguration() + */ + public CertStoreConfiguration getCertStoreConfiguration() { + return certStoreConfiguration; + } + + /** + * @see iaik.pki.PKIConfiguration#getRevocationConfiguration() + */ + public RevocationConfiguration getRevocationConfiguration() { + return revocationConfiguration; + } + + /** + * @see iaik.pki.PKIConfiguration#getArchiveConfiguration() + */ + public ArchiveConfiguration getArchiveConfiguration() { + return archiveConfiguration; + } + + /** + * @see iaik.pki.PKIConfiguration#getValidationConfiguration() + */ + public ValidationConfiguration getValidationConfiguration() { + return validationConfiguration; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/RevocationConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/RevocationConfigurationImpl.java new file mode 100644 index 000000000..466234a11 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/RevocationConfigurationImpl.java @@ -0,0 +1,73 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import iaik.pki.revocation.RevocationConfiguration; + +import at.gv.egovernment.moa.util.BoolUtils; + +import at.gv.egovernment.moa.spss.server.config.DistributionPoint; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * An implementation of the <code>RevocationConfiguration</code> interface using + * MOA configuration data. + * + * @see iaik.pki.revocation.RevocationConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public class RevocationConfigurationImpl + extends AbstractObservableConfiguration + implements RevocationConfiguration { + + /** The <code>ConfigurationProvider</code> to read the configuration data + * from. */ + private ConfigurationProvider config; + + /** + * Create a new <code>RevocationConfigurationImpl</code>. + * + * @param config The underlying MOA configuration containing the configuration + * data. + */ + public RevocationConfigurationImpl(ConfigurationProvider config) { + this.config = config; + } + + /** + * @see iaik.pki.revocation.RevocationConfiguration#getAlternativeDistributionPoints(java.security.cert.X509Certificate, java.util.Date) + */ + public Set getAlternativeDistributionPoints( + X509Certificate cert, + Date date) { + + Set configuredPoints = config.getCRLDP(cert); + Set distributionPoints = new HashSet(); + Iterator iter; + + for (iter = configuredPoints.iterator(); iter.hasNext();) { + DistributionPoint dp = (DistributionPoint) iter.next(); + distributionPoints.add(new CRLDistributionPointAdapter(dp)); + } + + return distributionPoints; + } + + /** + * @see iaik.pki.revocation.RevocationConfiguration#archiveRevocationInfo(java.lang.String, java.lang.String) + */ + public boolean archiveRevocationInfo(String type, String uri) { + String info = + config.getGenericConfiguration( + ConfigurationProvider.ARCHIVE_REVOCATION_INFO_PROPERTY, + "false"); + + return info != null ? BoolUtils.valueOf(info) : false; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/SoftwareKeyModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/SoftwareKeyModuleConfigurationImpl.java new file mode 100644 index 000000000..343f096ef --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/SoftwareKeyModuleConfigurationImpl.java @@ -0,0 +1,75 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +import iaik.server.modules.keys.ConfigurationException; +import iaik.server.modules.keys.SoftwareKeyModuleConfiguration; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; + +import at.gv.egovernment.moa.spss.server.config.SoftwareKeyModule; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * An implementation of the <code>SoftwareKeyModuleConfiguration</code> wrapping + * a <code>SoftwareKeyModule</code> from the MOA configuration. + * + * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public class SoftwareKeyModuleConfigurationImpl + extends AbstractKeyModuleConfigurationImpl + implements SoftwareKeyModuleConfiguration { + + /** The wrapped <code>SoftwareKeyModule</code>. */ + private SoftwareKeyModule keyModule; + + /** + * Create a new <code>SoftwareKeyModuleConfigurationImpl</code>. + * + * @param keyModule The <code>SoftwareKeyModule</code> from the underlying MOA + * configuration. + */ + public SoftwareKeyModuleConfigurationImpl(SoftwareKeyModule keyModule) { + super(keyModule.getId()); + this.keyModule = keyModule; + } + + /** + * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration#getKeyStoreTypeName() + */ + public String getKeyStoreTypeName() { + return KEY_STORE_TYPE_NAME_PKCS12; + } + + /** + * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration#getKeyStoreAsStream() + */ + public InputStream getKeyStoreAsStream() { + MessageProvider msg = MessageProvider.getInstance(); + + try { + String message = + msg.getMessage("config.18", new Object[] { keyModule.getFileName()}); + Logger.info(new LogMsg(message)); + return new FileInputStream(keyModule.getFileName()); + } catch (FileNotFoundException e) { + String message = + msg.getMessage("config.09", new Object[] { keyModule.getFileName()}); + + throw new ConfigurationException(message, e, null); + } + } + + /** + * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration#getKeyStoreAuthenticationData() + */ + public char[] getKeyStoreAuthenticationData() { + return keyModule.getPassWord().toCharArray(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ValidationConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ValidationConfigurationImpl.java new file mode 100644 index 000000000..f6fbad215 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ValidationConfigurationImpl.java @@ -0,0 +1,56 @@ +package at.gv.egovernment.moa.spss.server.iaik.config; + +import java.security.cert.X509Certificate; +import java.security.spec.AlgorithmParameterSpec; + +import iaik.pki.pathvalidation.ValidationConfiguration; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * An implementation of the <code>ValidationConfiguration</code> interface using + * MOA configuration data. + * + * @see iaik.pki.pathvalidation.ValidationConfiguration + * @author Patrick Peck + * @version $Id$ + */ +public class ValidationConfigurationImpl + extends AbstractObservableConfiguration + implements ValidationConfiguration { + + /** The <code>ConfigurationProvider</code> to read the configuration data + * from. */ + private ConfigurationProvider config; + + /** + * Create a new <code>ValidationConfigurationImpl</code>. + * + * @param config The underlying MOA configuration data. + */ + public ValidationConfigurationImpl(ConfigurationProvider config) { + this.config = config; + } + + /** + * @see iaik.pki.pathvalidation.ValidationConfiguration#getChainingMode(java.security.cert.X509Certificate) + */ + public String getChainingMode(X509Certificate cert) { + return config.getChainingMode(cert); + } + + /** + * @see iaik.pki.pathvalidation.ValidationConfiguration#getPublicKeyParamsAsSpec(java.security.cert.X509Certificate) + */ + public AlgorithmParameterSpec getPublicKeyParamsAsSpec(X509Certificate cert) { + return null; + } + + /** + * @see iaik.pki.pathvalidation.ValidationConfiguration#getPublicKeyParamsAsCert(java.security.cert.X509Certificate) + */ + public X509Certificate getPublicKeyParamsAsCert(X509Certificate cert) { + return null; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/PKIProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/PKIProfileImpl.java new file mode 100644 index 000000000..c204eface --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/PKIProfileImpl.java @@ -0,0 +1,127 @@ +package at.gv.egovernment.moa.spss.server.iaik.pki; + +import iaik.pki.PKIProfile; +import iaik.pki.pathvalidation.ValidationProfile; +import iaik.pki.revocation.RevocationProfile; +import iaik.pki.store.truststore.TrustStoreProfile; + +import at.gv.egovernment.moa.util.BoolUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.pki.pathvalidation.ValidationProfileImpl; +import at.gv.egovernment.moa.spss.server.iaik.pki.revocation.RevocationProfileImpl; +import at.gv.egovernment.moa.spss.server.iaik.pki.store.truststore.TrustStoreProfileImpl; + +/** + * Implementation of the <code>PKIProfile</code> interface containing + * information needed for certificate path validation. It uses configuration + * data from the MOA configuration. + * + * @author Patrick Peck + * @version $Id$ + */ +public class PKIProfileImpl implements PKIProfile { + + /** Profile information for revocation checking. */ + private RevocationProfile revocationProfile; + /** Profile information about the trust profile to use. */ + private TrustStoreProfile trustStoreProfile; + /** Profile information about the certificate validation. */ + private ValidationProfile validationProfile; + /** The <code>ConfigurationProvider</code> to read the MOA configuration data + * from. */ + private ConfigurationProvider config; + + /** + * Create a new <code>PKIProfileImpl</code>. + * + * @param config The MOA configuration providing configuration data about + * certificate path validation. + * @param trustProfileID The trust profile ID denoting the location of the + * trust store. + * @throws MOAApplicationException An error occurred building the profile. + */ + public PKIProfileImpl(ConfigurationProvider config, String trustProfileID) + throws MOAApplicationException { + + this.config = config; + setRevocationProfile(new RevocationProfileImpl(config)); + setTrustStoreProfile(new TrustStoreProfileImpl(config, trustProfileID)); + setValidationProfile(new ValidationProfileImpl(config)); + } + + /** + * @see iaik.pki.PKIProfile#autoAddCertificates() + */ + public boolean autoAddCertificates() { + String boolStr = + config.getGenericConfiguration( + ConfigurationProvider.AUTO_ADD_CERTIFICATES_PROPERTY, + "true"); + boolean boolValue = BoolUtils.valueOf(boolStr); + + return useAuthorityInfoAccess() ? true : boolValue; + } + + /** + * @see iaik.pki.PKIProfile#getRevocationProfile() + */ + public RevocationProfile getRevocationProfile() { + return revocationProfile; + } + + /** + * Sets the <code>RevocationProfile</code>. + * + * @param revocationProfile The <code>RevocationProfile</code> used for + * revocation checking. + */ + protected void setRevocationProfile(RevocationProfile revocationProfile) { + this.revocationProfile = revocationProfile; + } + + /** + * @see iaik.pki.PKIProfile#getTrustStoreProfile() + */ + public TrustStoreProfile getTrustStoreProfile() { + return trustStoreProfile; + } + + /** + * Sets the <code>TrustStoreProfile</code>. + * + * @param trustStoreProfile The <code>TrustStoreProfile</code>. + */ + protected void setTrustStoreProfile(TrustStoreProfile trustStoreProfile) { + this.trustStoreProfile = trustStoreProfile; + } + + /** + * @see iaik.pki.PKIProfile#getValidationProfile() + */ + public ValidationProfile getValidationProfile() { + return validationProfile; + } + + /** + * Sets the <code>ValidationProfile</code>. + * + * @param validationProfile The <code>ValidationProfile</code> to set. + */ + protected void setValidationProfile(ValidationProfile validationProfile) { + this.validationProfile = validationProfile; + } + + /** + * @see iaik.pki.PKIProfile#useAuthorityInfoAccess() + */ + public boolean useAuthorityInfoAccess() { + String boolStr = + config.getGenericConfiguration( + ConfigurationProvider.USE_AUTHORITY_INFO_ACCESS_PROPERTY, + "true"); + return BoolUtils.valueOf(boolStr); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/pathvalidation/ValidationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/pathvalidation/ValidationProfileImpl.java new file mode 100644 index 000000000..3327b3a50 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/pathvalidation/ValidationProfileImpl.java @@ -0,0 +1,113 @@ +package at.gv.egovernment.moa.spss.server.iaik.pki.pathvalidation; + +import iaik.pki.pathvalidation.ValidationProfile; + +import at.gv.egovernment.moa.util.BoolUtils; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +import java.util.Collections; +import java.util.Set; + +/** + * An implementation of the <code>ValidationProfile</code> interface providing + * information about certificat path validation. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ValidationProfileImpl implements ValidationProfile { + + /** The <code>ConfigurationProvider</code> to read the configuration data + * from. */ + private ConfigurationProvider config; + private boolean initialAnyPolicyInhibit; + private boolean initialExplicitPolicy; + private boolean initialPolicyMappingInhibit; + private Set initialPolicySet; + private boolean nameConstraintsProcessing; + private boolean policyProcessing; + + /** + * Create a new <code>ValidationProfileImpl</code> object. + * + * This objects's fields are preset to the following values: + * + * <ul> + * <li><code>initialAnyPolicyInhibit = true</code></li> + * <li><code>initialExplicitPoliy = true</code></li> + * <li><code>initialPolicyMappingInhibit = true</code></li> + * <li><code>initialPolicySet = empty</code></li> + * <li><code>policyProcessing = false</code></li> + * <li><code>nameConstraintsProcessing = false</code></li> + * <li><code>revocationChecking = false</code></li> + * </ul> + * + * @param config MOA configuration data for additional configuration + * information (currently unused). + */ + public ValidationProfileImpl(ConfigurationProvider config) { + this.config = config; + initialAnyPolicyInhibit = true; + initialExplicitPolicy = true; + initialPolicyMappingInhibit = true; + initialPolicySet = Collections.EMPTY_SET; + policyProcessing = false; + nameConstraintsProcessing = false; + } + + /** + * @see iaik.pki.pathvalidation.ValidationProfile#getInitialAnyPolicyInhibit() + */ + public boolean getInitialAnyPolicyInhibit() { + return initialAnyPolicyInhibit; + } + + /** + * @see iaik.pki.pathvalidation.ValidationProfile#getInitialExplicitPolicy() + */ + public boolean getInitialExplicitPolicy() { + return initialExplicitPolicy; + } + + /** + * @see iaik.pki.pathvalidation.ValidationProfile#getInitialPolicyMappingInhibit() + */ + public boolean getInitialPolicyMappingInhibit() { + return initialPolicyMappingInhibit; + } + + /** + * @see iaik.pki.pathvalidation.ValidationProfile#getInitialPolicySet() + */ + public Set getInitialPolicySet() { + return initialPolicySet; + } + + /** + * @see iaik.pki.pathvalidation.ValidationProfile#getPolicyProcessing() + */ + public boolean getPolicyProcessing() { + return policyProcessing; + } + + /** + * @see iaik.pki.pathvalidation.ValidationProfile#getNameConstraintsProcessing() + */ + public boolean getNameConstraintsProcessing() { + return nameConstraintsProcessing; + } + + /** + * @see iaik.pki.pathvalidation.ValidationProfile#getRevocationChecking() + */ + public boolean getRevocationChecking() { + String checkingStr = + config.getGenericConfiguration( + ConfigurationProvider.REVOCATION_CHECKING_PROPERTY, + "false"); + + return BoolUtils.valueOf(checkingStr); + } + +}
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/revocation/RevocationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/revocation/RevocationProfileImpl.java new file mode 100644 index 000000000..186d24934 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/revocation/RevocationProfileImpl.java @@ -0,0 +1,65 @@ +package at.gv.egovernment.moa.spss.server.iaik.pki.revocation; + +import java.security.cert.X509Certificate; + +import iaik.pki.revocation.RevocationProfile; +import iaik.pki.revocation.RevocationSourceTypes; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * An implementation of the <code>RevocationProfile</code> interface providing + * information about revocation status checking, based on MOA configuration + * data. + * + * @author Patrick Peck + * @version $Id$ + */ +public class RevocationProfileImpl implements RevocationProfile { + /** The default service order. */ + private static final String[] DEFAULT_SERVICE_ORDER = + { RevocationSourceTypes.CRL }; + /** The <code>ConfigurationProvider</code> to read the MOA configuration data + * from. */ + private ConfigurationProvider config; + /** The OCSP request hash algorithm. */ + private String oCSPRequestHashAlgorithm; + + /** + * Create a new <code>RevocationProfileImpl</code>. + * + * @param config The MOA configuration data. + */ + public RevocationProfileImpl(ConfigurationProvider config) { + this.config = config; + this.oCSPRequestHashAlgorithm = ""; + } + + /** + * @see iaik.pki.revocation.RevocationProfile#getMaxRevocationAge(String) + */ + public long getMaxRevocationAge(String distributionPointUri) { + String maxRevocationAgeStr = + config.getGenericConfiguration( + ConfigurationProvider.MAX_REVOCATION_AGE_PROPERTY, + "0"); + long revocationAge = Long.parseLong(maxRevocationAgeStr); + + return revocationAge; + } + + /** + * @see iaik.pki.revocation.RevocationProfile#getOCSPRequestHashAlgorithm() + */ + public String getOCSPRequestHashAlgorithm() { + return oCSPRequestHashAlgorithm; + } + + /** + * @see iaik.pki.revocation.RevocationProfile#getPreferredServiceOrder(java.security.cert.X509Certificate) + */ + public String[] getPreferredServiceOrder(X509Certificate cert) { + return DEFAULT_SERVICE_ORDER; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/store/truststore/TrustStoreProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/store/truststore/TrustStoreProfileImpl.java new file mode 100644 index 000000000..8a1161b95 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/store/truststore/TrustStoreProfileImpl.java @@ -0,0 +1,119 @@ +package at.gv.egovernment.moa.spss.server.iaik.pki.store.truststore; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import iaik.pki.store.truststore.TrustStoreProfile; +import iaik.pki.store.truststore.TrustStoreTypes; +import iaik.servertools.observer.NotificationData; +import iaik.servertools.observer.Observer; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.config.TrustProfile; + +/** + * An implementation of the <code>TrustStoreProfile</code> interface, using data + * from the MOA configuration. + * + * @see iaik.pki.store.truststore.TrustStoreProfile + * @author Patrick Peck + * @version $Id$ + */ +public class TrustStoreProfileImpl implements TrustStoreProfile { + + /** The observers of this profile. */ + private List observers = new ArrayList(); + /** The type of the trust profile. */ + private String type; + /** The URI of the trust profile.*/ + private String URI; + + /** + * Create a new <code>TrustStoreProfileImpl</code>. + * + * @param config The MOA configuration data, from which trust store + * configuration data is read. + * @param trustProfileId The trust profile id on which this + * <code>TrustStoreProfile</code> is based. + * @throws MOAApplicationException The <code>trustProfileId</code> could not + * be found in the MOA configuration. + */ + public TrustStoreProfileImpl( + ConfigurationProvider config, + String trustProfileId) + throws MOAApplicationException { + + TrustProfile tp = (TrustProfile) config.getTrustProfile(trustProfileId); + if (tp != null) { + setURI(tp.getUri()); + setType(TrustStoreTypes.DIRECTORY); + } else { + throw new MOAApplicationException( + "2203", + new Object[] { trustProfileId }); + } + } + + /** + * @see iaik.pki.store.truststore.TrustStoreProfile#getType() + */ + public String getType() { + return type; + } + + /** + * Sets the the trust store type. + * + * @param type The trust store type to set. + */ + protected void setType(String type) { + this.type = type; + } + + /** + * @see iaik.pki.store.truststore.TrustStoreProfile#getURI() + */ + public String getURI() { + return URI; + } + + /** + * Sets the trust store URI. + * + * @param URI The trust store URI to set. + */ + protected void setURI(String URI) { + this.URI = URI; + } + + // + // Methods of iaik.utils.observer.Observable interface + // + + /** + * @see iaik.utils.observer.Observable#addObserver(Observer) + */ + public void addObserver(Observer observer) { + observers.add(observer); + } + + /** + * @see iaik.utils.observer.Observable#removeObserver(Observer) + */ + public boolean removeObserver(Observer observer) { + return observers.remove(observer); + } + + /** + * @see iaik.utils.observer.Observable#notify(NotificationData) + */ + public void notify(NotificationData notificationData) { + for (Iterator iter = observers.iterator(); iter.hasNext();) { + Observer observer = (Observer) iter.next(); + observer.notify(notificationData); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/Base64TransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/Base64TransformationImpl.java new file mode 100644 index 000000000..e076fe1eb --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/Base64TransformationImpl.java @@ -0,0 +1,43 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import iaik.server.modules.xml.Base64Transformation; + +/** + * An implementation of the <code>Base64Transformation</code> + * <code>Transformation</code> type. + * + * @author Patrick Peck + * @version $Id$ + */ +public class Base64TransformationImpl + extends TransformationImpl + implements Base64Transformation { + + /** + * Create a new <code>Base64TransformationImpl</code>. + * + * @see java.lang.Object#Object() + */ + public Base64TransformationImpl() { + setAlgorithmURI(Base64Transformation.BASE64_DECODING); + } + + /** + * Compare this <code>Base64Transformation</code> to another. + * + * @param other The object to compare this<code>Base64Transformation</code> + * to. + * @return <code>true</code>, if <code>other</code> is a + * <code>Base64Transformation</code> and the algorithm URIs match, otherwise + * <code>false</code>. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof Base64Transformation) { + Base64Transformation transform = (Base64Transformation) other; + return getAlgorithmURI().equals(transform.getAlgorithmURI()); + } + return false; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteArrayDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteArrayDataObjectImpl.java new file mode 100644 index 000000000..921b10cb6 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteArrayDataObjectImpl.java @@ -0,0 +1,54 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import iaik.server.modules.xml.BinaryDataObject; + +/** + * A <code>BinaryDataObject</code> encapsulating Base64 data. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ByteArrayDataObjectImpl + extends DataObjectImpl + implements BinaryDataObject { + + /** The binary data contained in this <code>BinaryDataObject</code>. */ + private byte[] bytes; + + /** + * Create a new <code>ByteArrayDataObjectImpl</code>. + * + * @param bytes The binary data contained in this + * <code>BinaryDataObject</code>. + */ + public ByteArrayDataObjectImpl(byte[] bytes) { + setBytes(bytes); + } + + /** + * Set the Base64 data. + * + * @param bytes The binary data contained in this + * <code>BinaryDataObject</code>. + */ + public void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + /** + * Return the binary data encoded in the Base64 <code>String</code> as a + * stream. + * + * @return The binary data contained in this object, as a + * <code>InputStream</code>. Repeated calls to this function will return a + * new stream to the Base64 data. + * @see iaik.server.modules.xml.BinaryDataObject#getInputStream() + */ + public InputStream getInputStream() { + return new ByteArrayInputStream(bytes); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteStreamDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteStreamDataObjectImpl.java new file mode 100644 index 000000000..ce400e61a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteStreamDataObjectImpl.java @@ -0,0 +1,49 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.io.InputStream; + +import iaik.server.modules.xml.BinaryDataObject; + +/** + * A <code>BinaryDataObject</code> encapsulating binary data from a stream. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ByteStreamDataObjectImpl + extends DataObjectImpl + implements BinaryDataObject { + + /** The <code>InputStream</code> containing the binary data. */ + private InputStream inputStream; + + /** + * Create a new <code>ByteStreamDataObjectImpl</code>. + * + * @param inputStream The stream from which to read the binary data. + */ + public ByteStreamDataObjectImpl(InputStream inputStream) { + setInputStream(inputStream); + } + + /** + * Set the input stream from which to read the binary data. + * + * @param inputStream The input stream from which to read the binary data. + */ + public void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; + } + + /** + * Return the binary data from this object as a stream. + * + * @return The stream containing the binary data. Calling this function + * repeatedly will always return the same <code>InputStream</code>. + * @see iaik.server.modules.xml.BinaryDataObject#getInputStream() + */ + public InputStream getInputStream() { + return inputStream; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/CanonicalizationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/CanonicalizationImpl.java new file mode 100644 index 000000000..a597b214d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/CanonicalizationImpl.java @@ -0,0 +1,43 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import iaik.server.modules.xml.Canonicalization; + +/** + * An implementation of the <code>CanonicalizationTransform</code> + * <code>Transformation</code> type. + * + * @author Patrick Peck + * @version $Id$ + */ +public class CanonicalizationImpl + extends TransformationImpl + implements Canonicalization { + + /** + * Create a new <code>CanonicalizationTransformImpl</code> object. + * + * @param algorithmURI The canonicalization algorithm URI. + */ + public CanonicalizationImpl(String algorithmURI) { + setAlgorithmURI(algorithmURI); + } + + /** + * Compare this object to another <code>Canonicalization</code>. + * + * @param other The object to compare this + * <code>Canonicalization</code> to. + * @return <code>true</code>, if <code>other</code> is a + * <code>Canonicalization</code> and the algorithm URIs match, otherwise + * <code>false</code>. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof Canonicalization) { + Canonicalization c14n = (Canonicalization) other; + return getAlgorithmURI().equals(c14n.getAlgorithmURI()); + } + return false; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/DataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/DataObjectImpl.java new file mode 100644 index 000000000..875d82613 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/DataObjectImpl.java @@ -0,0 +1,87 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import iaik.server.modules.xml.DataObject; + +/** + * Abstract base implementation for the classes derived from + * <code>DataObject</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class DataObjectImpl implements DataObject { + + /** The MIME type of the data object. */ + private String mimeType; + /** The refernce ID. */ + private String referenceID; + /** The URI of the type. */ + private String typeURI; + /** The URI identifying the data. */ + private String URI; + + /** + * @see iaik.server.modules.xml.DataObject#getMimeType() + */ + public String getMimeType() { + return mimeType; + } + + /** + * Set the mime type. + * + * @param mimeType The mime type to set. + */ + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + /** + * @see iaik.server.modules.xml.DataObject#getReferenceID() + */ + public String getReferenceID() { + return referenceID; + } + + /** + * Set the reference ID. + * + * @param referenceID The reference ID. + */ + public void setReferenceID(String referenceID) { + this.referenceID = referenceID; + } + + /** + * @see iaik.server.modules.xml.DataObject#getTypeURI() + */ + public String getTypeURI() { + return typeURI; + } + + /** + * Set the type URI. + * + * @param typeURI The type URI. + */ + public void setTypeURI(String typeURI) { + this.typeURI = typeURI; + } + + /** + * @see iaik.server.modules.xml.DataObject#getURI() + */ + public String getURI() { + return URI; + } + + /** + * Set the URI. + * + * @param URI The URI. + */ + public void setURI(String URI) { + this.URI = URI; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/EnvelopedSignatureTransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/EnvelopedSignatureTransformationImpl.java new file mode 100644 index 000000000..41a47d0a1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/EnvelopedSignatureTransformationImpl.java @@ -0,0 +1,42 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import iaik.server.modules.xml.EnvelopedSignatureTransformation; + +/** + * An implementation of the <code>EnvelopedSignatureTransformation</code> + * <code>Transformation</code> type. + * + * @author Patrick Peck + * @version $Id$ + */ +public class EnvelopedSignatureTransformationImpl + extends TransformationImpl + implements EnvelopedSignatureTransformation { + + /** + * Create a new <code>EnvelopedSignatureTransformationImpl</code>. + */ + public EnvelopedSignatureTransformationImpl() { + setAlgorithmURI(EnvelopedSignatureTransformation.ENVELOPED_SIGNATURE); + } + + /** + * Compare this object to another <code>EnvelopedSignatureTransformation</code>. + * + * @param other The object to compare this + * <code>EnvelopedSignatureTransformation</code> to. + * @return <code>true</code>, if <code>other</code> is a + * <code>EnvelopedSignatureTransformation</code>, otherwise + * <code>false</code>. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof EnvelopedSignatureTransformation) { + EnvelopedSignatureTransformation transform = + (EnvelopedSignatureTransformation) other; + return getAlgorithmURI().equals(transform.getAlgorithmURI()); + } + return false; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ExclusiveCanonicalizationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ExclusiveCanonicalizationImpl.java new file mode 100644 index 000000000..f50d0d9b1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ExclusiveCanonicalizationImpl.java @@ -0,0 +1,71 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.util.List; + +import iaik.server.modules.xml.ExclusiveCanonicalization; + +/** + * An implementation of the <code>ExclusiveCanonicalization</code> type + * of <code>Transformation</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ExclusiveCanonicalizationImpl + extends TransformationImpl + implements ExclusiveCanonicalization { + + /** The prefixes of the namespaces to treat according to canonical XML. */ + private List inclusiveNamespacePrefixes; + + /** + * Create a new <code>ExclusiveCanonicalizationImpl</code> object. + * + * @param algorithmURI The exclusive canonicalization algorithm URI. + * @param inclusiveNamespacePrefixes The namespace prefixes to be processed + * according to canonical XML. + */ + public ExclusiveCanonicalizationImpl( + String algorithmURI, + List inclusiveNamespacePrefixes) { + setAlgorithmURI(algorithmURI); + setInclusiveNamespacePrefixes(inclusiveNamespacePrefixes); + } + + /** + * Sets the namespace prefixes to be processed according to canonical XML. + * + * @param inclusiveNamespacePrefixes The prefixes of the namespaces to treat + * according to canonical XML. + */ + protected void setInclusiveNamespacePrefixes(List inclusiveNamespacePrefixes) { + this.inclusiveNamespacePrefixes = inclusiveNamespacePrefixes; + } + + /** + * @see iaik.server.modules.xml.ExclusiveCanonicalization#getInclusiveNamespacePrefixes() + */ + public List getInclusiveNamespacePrefixes() { + return inclusiveNamespacePrefixes; + } + + /** + * Compare this object to another <code>CanonicalizationTransform</code>. + * + * @param other The object to compare this + * <code>ExclusiveCanonicalization</code> to. + * @return <code>true</code>, if <code>other</code> is a + * <code>ExclusiveCanonicalization</code> and the algorithm URIs match, + * otherwise <code>false</code>. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof ExclusiveCanonicalizationImpl) { + ExclusiveCanonicalizationImpl c14n = + (ExclusiveCanonicalizationImpl) other; + return getAlgorithmURI().equals(c14n.getAlgorithmURI()); + } + return false; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/SigningTimeImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/SigningTimeImpl.java new file mode 100644 index 000000000..19ca3dadf --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/SigningTimeImpl.java @@ -0,0 +1,34 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.util.Date; + +import iaik.server.modules.xml.SigningTime; + +/** + * An implementation of the <code>SigningTime</code> <code>Property</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SigningTimeImpl implements SigningTime { + + /** The signing time. */ + private Date signingTime; + + /** + * Create a new <code>SigningTimeImpl</code>. + * + * @param signingTime The signing time. + */ + public SigningTimeImpl(Date signingTime) { + this.signingTime = signingTime; + } + + /** + * @see iaik.server.modules.xml.SigningTime#getSigningTime() + */ + public Date getSigningTime() { + return signingTime; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/TransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/TransformationImpl.java new file mode 100644 index 000000000..59a414b69 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/TransformationImpl.java @@ -0,0 +1,43 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import iaik.server.modules.xml.Transformation; + +/** + * Base implementation class for <code>Transformation</code> derived classes. + * + * @author Patrick Peck + * @version $Id$ + */ +public abstract class TransformationImpl implements Transformation { + + /** The algorithm URI identifying the transformation algorithm. */ + private String algorithmURI; + + /** + * @see iaik.server.modules.xml.Transformation#getAlgorithmURI() + */ + public String getAlgorithmURI() { + return algorithmURI; + } + + /** + * Sets the algorithm URI. + * + * @param algorithmURI The algorithm URI to set. + */ + protected void setAlgorithmURI(String algorithmURI) { + this.algorithmURI = algorithmURI; + } + + /** + * Returns the hash code of the algorithm URI. Should be overridden if a + * transformation distinguishes itself from others by more than just the + * algorithm URI. + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getAlgorithmURI().hashCode(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLDataObjectImpl.java new file mode 100644 index 000000000..bc31d694e --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLDataObjectImpl.java @@ -0,0 +1,46 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import org.w3c.dom.Element; + +import iaik.server.modules.xml.XMLDataObject; + +/** + * A <code>DataObject</code> containing a single DOM element. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLDataObjectImpl + extends DataObjectImpl + implements XMLDataObject { + + /** The XML data contained in this <code>XMLDataObject</code>. */ + private Element element; + + /** + * Create a new <code>XMLDataObjectImpl</code>. + * + * @param element The DOM element contained in this + * <code>XMLDataObject</code>. + */ + public XMLDataObjectImpl(Element element) { + setElement(element); + } + + /** + * @see iaik.server.modules.xml.XMLDataObject#getElement() + */ + public Element getElement() { + return element; + } + + /** + * Set the DOM element contained in this <code>XMLDataObject</code>. + * + * @param element The DOM element to set. + */ + public void setElement(Element element) { + this.element = element; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLNodeListDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLNodeListDataObjectImpl.java new file mode 100644 index 000000000..c855a922a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLNodeListDataObjectImpl.java @@ -0,0 +1,47 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import org.w3c.dom.NodeList; + +import iaik.server.modules.xml.XMLNodeListDataObject; + +/** + * A <code>DataObject</code> containing a list of DOM nodes. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLNodeListDataObjectImpl + extends DataObjectImpl + implements XMLNodeListDataObject { + + /** The nodes contained in this <code>XMLNodeListDataObject</code>. */ + private NodeList nodeList; + + /** + * Create a new <code>XMLNodeListDataObjectImpl</code>. + * + * @param nodeList The list of DOM nodes contained in this + * <code>XMLNodeListDataObject</code>. + */ + public XMLNodeListDataObjectImpl(NodeList nodeList) { + setNodeList(nodeList); + } + + /** + * Set the list of DOM nodes contained in this + * <code>XMLNodeListDataObject</code>. + * + * @param nodeList The list of DOM nodes to set. + */ + public void setNodeList(NodeList nodeList) { + this.nodeList = nodeList; + } + + /** + * @see iaik.server.modules.xml.XMLNodeListDataObject#getNodeList() + */ + public NodeList getNodeList() { + return nodeList; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLSignatureImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLSignatureImpl.java new file mode 100644 index 000000000..4fca907f3 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLSignatureImpl.java @@ -0,0 +1,43 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import org.w3c.dom.Element; + +import iaik.server.modules.xml.XMLSignature; + +/** + * An object containing an XMLDsig signature in the form of a + * <code>dsig:Signature</code> DOM element. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureImpl implements XMLSignature { + /** The signature DOM element. */ + private Element element; + + /** + * Create a new <code>XMLSignatureImpl</code>. + * + * @param element The <code>dsig:Signature</code> DOM element. + */ + public XMLSignatureImpl(Element element) { + setElement(element); + } + + /** + * Set the <code>dsig:Signature</code> DOM element. + * + * @param element The <code>dsig:Signature</code> element to set. + */ + public void setElement(Element element) { + this.element = element; + } + + /** + * @see iaik.server.modules.xml.XMLSignature#getElement() + */ + public Element getElement() { + return element; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2FilterImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2FilterImpl.java new file mode 100644 index 000000000..034d4b653 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2FilterImpl.java @@ -0,0 +1,116 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.util.Map; + +import iaik.server.modules.xml.XPath2Transformation; +import iaik.server.modules.xml.XPath2Transformation.XPath2Filter; + +/** + * An object encapsulating an XPath-Filter2 expression. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XPath2FilterImpl implements XPath2Filter { + + /** The type of this filter. */ + private String filterType; + /** The XPath expression of this filter. */ + private String xPathExpression; + /** The namespace prefix to URI mapping to use for evaluating the XPath. */ + private Map namespaceDeclarations; + + /** + * Create a new <code>XPath2FilterImpl</code> object. + * + * @param filterType The type of filter. Must be one of the filter type + * constants declared in <code>iaik.server.modules.xml.XPath2Transformation.XPath2Filter</code> + * @param xPathExpression The XPath expression belonging to this filter. + * @param namespaceDeclarations The namespace declarations visible for this + * XPath2Filter. + */ + public XPath2FilterImpl( + String filterType, + String xPathExpression, + Map namespaceDeclarations) { + + setFilterType(filterType); + setXPathExpression(xPathExpression); + setNamespaceDeclarations(namespaceDeclarations); + } + + /** + * @see iaik.server.modules.xml.XPath2Transformation.XPath2Filter#getFilterType() + */ + public String getFilterType() { + return filterType; + } + + /** + * Set the filter type. + * + * @param filterType The filter type to set. + */ + protected void setFilterType(String filterType) { + this.filterType = filterType; + } + + /** + * @see iaik.server.modules.xml.XPath2Transformation.XPath2Filter#getXPathExpression() + */ + public String getXPathExpression() { + return xPathExpression; + } + + /** + * Set the XPath expression. + * + * @param xPathExpression The XPath expression to set. + */ + protected void setXPathExpression(String xPathExpression) { + this.xPathExpression = xPathExpression; + } + + /** + * @see iaik.server.modules.xml.XPath2Transformation.XPath2Filter#getNamespaceDeclarations() + */ + public Map getNamespaceDeclarations() { + return namespaceDeclarations; + } + + /** + * Set the namespace declarations. + * + * @param namespaceDeclarations The mapping between namespace prefixes and + * their associated URI. + */ + protected void setNamespaceDeclarations(Map namespaceDeclarations) { + this.namespaceDeclarations = namespaceDeclarations; + } + + /** + * Compare this object to another. + * + * @param other The object to compare this <code>XPath2Filter</code> to. + * @return <code>true</code>, if <code>other</code> is a + * <code>XPath2Filter</code> and the filter types match and the XPath + * expressions match. Otherwise <code>false</code> is returned. + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object other) { + if (other instanceof XPath2Transformation.XPath2Filter) { + XPath2Filter filter = (XPath2Transformation.XPath2Filter) other; + return getFilterType().equals(filter.getFilterType()) + && getXPathExpression().equals(filter.getXPathExpression()); + } + return false; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getXPathExpression().hashCode() * 31 + getFilterType().hashCode(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2TransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2TransformationImpl.java new file mode 100644 index 000000000..c7496c2cd --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2TransformationImpl.java @@ -0,0 +1,82 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import iaik.server.modules.xml.XPath2Transformation; + +/** + * An object encapsulating a <code>Transformation</code> containing several + * XPath-Filter2 expressions. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XPath2TransformationImpl + extends TransformationImpl + implements XPath2Transformation { + + /** The filters contained in this <code>XPath2Transformation</code> */ + private List xPathFilters = new ArrayList(); + + /** + * Create a new <code>XPath2TransformationImpl</code>. + * + * The list of XPath-Filter2 expression is initially empty. + */ + public XPath2TransformationImpl() { + setAlgorithmURI(XPath2Transformation.XPATH2); + } + + /** + * @see iaik.server.modules.xml.XPath2Transformation#getXPathFilters() + */ + public List getXPathFilters() { + return xPathFilters; + } + + /** + * Add an XPath-Filter2 expression to the list of filters. + * + * @param filter The filter to add. + */ + public void addXPathFilter(XPath2Filter filter) { + xPathFilters.add(filter); + } + + /** + * Compare this <code>XPath2Transformation</code> to another. + * + * @param other The object to compare this + * <code>XPath2Transformation</code> to. + * @return <code>true</code>, if <code>other</code> is an + * <code>XPath2Transformation</code> and <code>getXPathFilters()</code> equals + * <code>other.getXPathFilters()</code>. Otherwise <code>false</code> is + * returned. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof XPath2Transformation) { + XPath2Transformation transform = (XPath2Transformation) other; + + return getXPathFilters().equals(transform.getXPathFilters()); + } + return false; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + Iterator iter = getXPathFilters().iterator(); + int hashCode = 0; + + while (iter.hasNext()) { + hashCode ^= iter.next().hashCode(); + } + + return hashCode; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPathTransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPathTransformationImpl.java new file mode 100644 index 000000000..ccedbadb2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPathTransformationImpl.java @@ -0,0 +1,98 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.util.Map; + +import iaik.server.modules.xml.XPathTransformation; + +/** + * A <code>Transformation</code> containing an XPath expression. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XPathTransformationImpl + extends TransformationImpl + implements XPathTransformation { + + /** The XPath expression. */ + private String xPathExpression; + /** The namespace prefix to URI mapping to use for XPath evaluation. */ + private Map namespaceDeclarations; + + /** + * Create a new <code>XPathTransformationImpl</code>. + * + * The namespace declarations are initialized empty. + * + * @param xPathExpression The XPath expression this object will contain. + * @param namespaceDeclarations The namespace declarations visible for this + * XPath. + */ + public XPathTransformationImpl( + String xPathExpression, + Map namespaceDeclarations) { + + setAlgorithmURI(XPathTransformation.XPATH); + setXPathExpression(xPathExpression); + setNamespaceDeclarations(namespaceDeclarations); + } + + /** + * Set the XPath expression. + * + * @param xPathExpression The XPath expression. + */ + protected void setXPathExpression(String xPathExpression) { + this.xPathExpression = xPathExpression; + } + + /** + * @see iaik.server.modules.xml.XPathTransformation#getXPathExpression() + */ + public String getXPathExpression() { + return xPathExpression; + } + + /** + * @see iaik.server.modules.xml.XPathTransformation#getNamespaceDeclarations() + */ + public Map getNamespaceDeclarations() { + return namespaceDeclarations; + } + + /** + * Set the namespace declarations. + * + * @param namespaceDeclarations The mapping between namespace prefixes and + * their associated URI. + */ + protected void setNamespaceDeclarations(Map namespaceDeclarations) { + this.namespaceDeclarations = namespaceDeclarations; + } + + /** + * Compare this <code>XPathTransformation</code> to another. + * + * @param other The object to compare this + * <code>XPathTransformation</code> to. + * @return <code>true</code>, if <code>other</code> is an + * <code>XPathTransformation</code> and if this object contains the same XPath + * expression as <code>other</code>. Otherwise <code>false</code> is returned. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof XPathTransformation) { + XPathTransformation transform = (XPathTransformation) other; + return getXPathExpression().equals(transform.getXPathExpression()); + } + return false; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getXPathExpression().hashCode(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java new file mode 100644 index 000000000..d38da650b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java @@ -0,0 +1,168 @@ +package at.gv.egovernment.moa.spss.server.iaik.xml; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import iaik.ixsil.algorithms.CanonicalizationAlgorithm; +import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplExclusiveCanonicalXML; +import iaik.ixsil.exceptions.AlgorithmException; +import iaik.server.modules.xml.XSLTTransformation; + +import at.gv.egovernment.moa.util.NodeListAdapter; +import at.gv.egovernment.moa.util.StreamUtils; +import at.gv.egovernment.moa.util.XPathException; +import at.gv.egovernment.moa.util.XPathUtils; + + +/** + * A <code>Transformation</code> containing an XSLT transformation. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XSLTTransformationImpl + extends TransformationImpl + implements XSLTTransformation { + + /** The XSLT stylesheet. */ + private Element styleSheetElement; + /** The hash code of the canonicalized stylesheet. If calculated, this value + * should be != 0. */ + private int hashCode; + + /** + * Create a new <code>XSLTTransformationImpl</code> object. + * + * @param styleSheetElement The XSLT stylesheet element. + */ + public XSLTTransformationImpl(Element styleSheetElement) { + setAlgorithmURI(XSLTTransformation.XSLT); + setStyleSheetElement(styleSheetElement); + } + + /** + * Set the XSLT stylesheet element. + * + * @param styleSheetElement The XSLT stylesheet element to set. + */ + protected void setStyleSheetElement(Element styleSheetElement) { + this.styleSheetElement = styleSheetElement; + this.hashCode = 0; + } + + /** + * @see iaik.server.modules.xml.XSLTTransformation#getStylesheetElement() + */ + public Element getStylesheetElement() { + return styleSheetElement; + } + + /** + * Compare this <code>XSLTTransformation</code> to another. + * + * @param other The object to compare this + * <code>XSLTTransformation</code> to. + * @return <code>true</code>, if <code>other</code> is an + * <code>XSLTTransformation</code> and if the canonicalized representations of + * the stylesheets contained in <code>this</code> and <code>other</code> + * match. Otherwise, <code>false</code> is returned. + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object other) { + if (other instanceof XSLTTransformation) { + XSLTTransformation xslt = (XSLTTransformation) other; + + return compareElements( + getStylesheetElement(), + xslt.getStylesheetElement()); + } + return false; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = calculateHashCode(getStylesheetElement()); + } + return hashCode; + } + + /** + * Calculate the hash code for a DOM element by canonicalizing it. + * + * @param element The DOM element for which the hash code is to be calculated. + * @return int The hash code, or <code>0</code>, if it could not be + * calculated. + */ + private static int calculateHashCode(Element element) { + try { + InputStream is = canonicalize(element); + byte[] buf = new byte[256]; + int hashCode = 1; + int length; + int i; + + while ((length = is.read(buf)) > 0) { + for (i = 0; i < length; i++) { + hashCode += buf[i] * 31 + i; + } + } + is.close(); + return hashCode; + } catch (AlgorithmException e) { + return 0; + } catch (IOException e) { + return 0; + } + } + + /** + * Compare two DOM elements by canonicalizing their contents and comparing the + * resulting byte stream. + * + * @param elem1 The 1st element to compare. + * @param elem2 The 2nd element to compare. + * @return boolean <code>true</code>, if the elements are considered equal + * after canonicalization. Otherwise <code>false</code> is returned. + */ + private static boolean compareElements(Element elem1, Element elem2) { + try { + InputStream is1 = canonicalize(elem1); + InputStream is2 = canonicalize(elem2); + return StreamUtils.compareStreams(is1, is2); + } catch (AlgorithmException e) { + return false; + } catch (IOException e) { + return false; + } + } + + /** + * Canonicalize a DOM element. + * + * @param element The element to canonicalize. + * @return InputStream A stream with the canonicalized data. + * @throws AlgorithmException An error occurred canonicalizing the element. + */ + private static InputStream canonicalize(Element element) + throws AlgorithmException { + CanonicalizationAlgorithm c14n = + new CanonicalizationAlgorithmImplExclusiveCanonicalXML(); + NodeList nodeList; + + try { + nodeList = XPathUtils.selectNodeList(element, XPathUtils.ALL_NODES_XPATH); + } catch (XPathException e) { + nodeList = new NodeListAdapter(Collections.EMPTY_LIST); + } + c14n.setInput(nodeList); + return c14n.canonicalize(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/DataObjectTreatmentImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/DataObjectTreatmentImpl.java new file mode 100644 index 000000000..a14b83b7d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/DataObjectTreatmentImpl.java @@ -0,0 +1,150 @@ +package at.gv.egovernment.moa.spss.server.iaik.xmlsign; + +import java.util.List; + +import iaik.server.modules.xmlsign.DataObjectTreatment; + +import at.gv.egovernment.moa.spss.server.util.IdGenerator; + +/** + * An object encapsulating how to treat an associated <code>DataObject</code> + * when creating a signature. + * + * @author Patrick Peck + * @version $Id$ + */ +public class DataObjectTreatmentImpl implements DataObjectTreatment { + /** The final content MIME type. */ + private String finalContentType; + /** The name of the hash algorithm. */ + private String hashAlgorithmName; + /** This transformations to apply to the associated data object. */ + private List transformationList; + /** Supplemental information for the transformations. */ + private List transformationSupplements; + /** Whether to include the associated data object in the signature. */ + private boolean includedInSignature; + /** Whether to include the associated data object in the manifest. */ + private boolean referenceInManifest; + /** The object ID generator. */ + private IdGenerator objIdGen; + + /** + * Create a new <code>DataObjectTreatmentImpl</code>. + * + * @param objIdGen The <code>IdGenerator</code> for unique object IDs. + */ + public DataObjectTreatmentImpl(IdGenerator objIdGen) { + this.objIdGen = objIdGen; + } + + /** + * @see iaik.server.modules.xmlsign.DataObjectTreatment#getFinalContentType() + */ + public String getFinalContentType() { + return finalContentType; + } + + /** + * Sets the final content type. + * + * @param finalContentType The final content type to set (a MIME-type type of + * <code>String</code>). + */ + public void setFinalContentType(String finalContentType) { + this.finalContentType = finalContentType; + } + + /** + * @see iaik.server.modules.xmlsign.DataObjectTreatment#getHashAlgorithmName() + */ + public String getHashAlgorithmName() { + return hashAlgorithmName; + } + + /** + * Sets the hash algorithm name. + * + * @param hashAlgorithmName The hash algorithm name to set. + */ + public void setHashAlgorithmName(String hashAlgorithmName) { + this.hashAlgorithmName = hashAlgorithmName; + } + + /** + * @see iaik.server.modules.xmlsign.DataObjectTreatment#isIncludedInSignature() + */ + public boolean isIncludedInSignature() { + return includedInSignature; + } + + /** + * Sets whether the associated <code>DataObject</code> is to be included in + * the signature. + * + * @param includedInSignature If <code>true</code>, the associated + * <code>DataObject</code> will be included in the signature, otherwise not. + */ + public void setIncludedInSignature(boolean includedInSignature) { + this.includedInSignature = includedInSignature; + } + + /** + * @see iaik.server.modules.xmlsign.DataObjectTreatment#isReferenceInManifest() + */ + public boolean isReferenceInManifest() { + return referenceInManifest; + } + + /** + * Sets whether the associated <code>DataObject</code> is + * to be included in the <code>dsig:Manifest</code>. + * + * @param referenceInManifest If <code>true</code>, the associated + * <code>DataObject</code> will be included in the manifest, otherwise not. + */ + public void setReferenceInManifest(boolean referenceInManifest) { + this.referenceInManifest = referenceInManifest; + } + + /** + * @see iaik.server.modules.xmlsign.DataObjectTreatment#getTransformationList() + */ + public List getTransformationList() { + return transformationList; + } + + /** + * Set the list of transformations for the associated <code>DataObject</code>. + * + * @param transformationList The transformations to set. + */ + public void setTransformationList(List transformationList) { + this.transformationList = transformationList; + } + + /** + * @see iaik.server.modules.xmlsign.DataObjectTreatment#getTransformationSupplements() + */ + public List getTransformationSupplements() { + return transformationSupplements; + } + + /** + * Sets the transformation supplements for the associated + * <code>DataObject</code>. + * + * @param transformationSupplements The transformation supplements to set. + */ + public void setTransformationSupplements(List transformationSupplements) { + this.transformationSupplements = transformationSupplements; + } + + /** + * @see iaik.server.modules.xmlsign.DataObjectTreatment#getDsigDataObjectID() + */ + public String getDsigDataObjectID() { + return objIdGen.uniqueId(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureCreationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureCreationProfileImpl.java new file mode 100644 index 000000000..5ec0057fb --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureCreationProfileImpl.java @@ -0,0 +1,276 @@ +package at.gv.egovernment.moa.spss.server.iaik.xmlsign; + +import java.util.List; +import java.util.Set; + +import iaik.server.modules.algorithms.SignatureAlgorithms; +import iaik.server.modules.keys.AlgorithmUnavailableException; +import iaik.server.modules.keys.KeyEntryID; +import iaik.server.modules.keys.KeyModule; +import iaik.server.modules.keys.KeyModuleFactory; +import iaik.server.modules.keys.UnknownKeyException; +import iaik.server.modules.xml.Canonicalization; +import iaik.server.modules.xmlsign.XMLSignatureCreationProfile; +import iaik.server.modules.xmlsign.XMLSignatureInsertionLocation; + +import at.gv.egovernment.moa.spss.server.logging.TransactionId; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; +import at.gv.egovernment.moa.spss.server.util.IdGenerator; + +/** + * An object providing auxiliary information for creating an XML signature. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureCreationProfileImpl + implements XMLSignatureCreationProfile { + + /** The transformations to apply to a data object. */ + private List dataObjectTreatmentList; + /** The set of keys available to the signing process. */ + private Set keySet; + /** The type URI of the signature manifest. */ + private String securityLayerManifestTypeURI; + /** Whether the created signature is to be Security Layer conform. */ + private boolean securityLayerConform; + /** Where to insert the signature into the signature environment. */ + private XMLSignatureInsertionLocation signatureInsertionLocation; + /** The signature structur type. */ + private String signatureStructureType; + /** The type of <code>Canonicalization</code> to use for the signed info. */ + private Canonicalization signedInfoCanonicalization; + /** Properties to be signed during signature creation. */ + private List signedProperties; + /** The ID generator for signature IDs. */ + private IdGenerator signatureIDGenerator; + /** The ID generator for manifst IDs. */ + private IdGenerator manifestIDGenerator; + /** The ID generator for XMLDsig manifest IDs. */ + private IdGenerator dsigManifestIDGenerator; + /** The ID generator for signed property IDs. */ + private IdGenerator propertyIDGenerator; + + /** + * Create a new <code>XMLSignatureCreationProfileImpl</code>. + * + * @param createProfileCount Provides external information about the + * number of calls to the signature creation module, using the same request. + * @param reservedIDs The set of IDs that must not be used while generating + * new IDs. + */ + public XMLSignatureCreationProfileImpl( + int createProfileCount, + Set reservedIDs) { + signatureIDGenerator = + new IdGenerator("signature-" + createProfileCount, reservedIDs); + manifestIDGenerator = + new IdGenerator("manifest-" + createProfileCount, reservedIDs); + dsigManifestIDGenerator = + new IdGenerator("dsig-manifest-" + createProfileCount, reservedIDs); + propertyIDGenerator = + new IdGenerator("etsi-signed-" + createProfileCount, reservedIDs); + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getDataObjectTreatmentList() + */ + public List getDataObjectTreatmentList() { + return dataObjectTreatmentList; + } + + /** + * Sets the list of <code>DataObjectTreatment</code>s. + * + * @param dataObjectTreatmentList The <code>DataObjectTreatment</code>s to + * set. + */ + public void setDataObjectTreatmentList(List dataObjectTreatmentList) { + this.dataObjectTreatmentList = dataObjectTreatmentList; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getKeySet() + */ + public Set getKeySet() { + return keySet; + } + + /** + * Set the set of <code>KeyEntryID</code>s which may be used for signature + * creation. + * + * @param keySet The set of <code>KeyEntryID</code>s to set. + */ + public void setKeySet(Set keySet) { + this.keySet = keySet; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSecurityLayerManifestTypeURI() + */ + public String getSecurityLayerManifestTypeURI() { + return securityLayerManifestTypeURI; + } + + /** + * Set the SecurityLayerManifestTypeURI. + * + * @param securityLayerManifestTypeURI The SecurityLayerManifestTypeURI to + * set. + */ + public void setSecurityLayerManifestTypeURI(String securityLayerManifestTypeURI) { + this.securityLayerManifestTypeURI = securityLayerManifestTypeURI; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureAlgorithmName(KeyEntryID) + */ + public String getSignatureAlgorithmName(KeyEntryID selectedKeyID) + throws AlgorithmUnavailableException { + + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + TransactionId tid = new TransactionId(context.getTransactionID()); + KeyModule module = KeyModuleFactory.getInstance(tid); + Set algorithms; + + try { + algorithms = module.getSupportedSignatureAlgorithms(selectedKeyID); + } catch (UnknownKeyException e) { + throw new AlgorithmUnavailableException( + "Unknown key entry: " + selectedKeyID, + e, + null); + } + + if (algorithms.contains(SignatureAlgorithms.MD2_WITH_RSA) + || algorithms.contains(SignatureAlgorithms.MD5_WITH_RSA) + || algorithms.contains(SignatureAlgorithms.RIPEMD128_WITH_RSA) + || algorithms.contains(SignatureAlgorithms.RIPEMD160_WITH_RSA) + || algorithms.contains(SignatureAlgorithms.SHA1_WITH_RSA) + || algorithms.contains(SignatureAlgorithms.SHA256_WITH_RSA)) { + + return SignatureAlgorithms.SHA1_WITH_RSA; + } else if ( + algorithms.contains(SignatureAlgorithms.ECDSA_X962_C2TNB191V1)) { + return SignatureAlgorithms.ECDSA_X962_C2TNB191V1; + } else { + throw new AlgorithmUnavailableException( + "No algorithm for key entry: " + selectedKeyID, + null, + null); + } + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureInsertionLocation() + */ + public XMLSignatureInsertionLocation getSignatureInsertionLocation() { + return signatureInsertionLocation; + } + + /** + * Set the location where the signature is to be inserted into the signature + * parent. + * + * @param signatureInsertionLocation The location to set. + */ + public void setSignatureInsertionLocation(XMLSignatureInsertionLocation signatureInsertionLocation) { + this.signatureInsertionLocation = signatureInsertionLocation; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureStructureType() + */ + public String getSignatureStructureType() { + return signatureStructureType; + } + + /** + * Set the signature structure type. + * @param signatureStructureType The signature structure type to set. + */ + public void setSignatureStructureType(String signatureStructureType) { + this.signatureStructureType = signatureStructureType; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignedInfoCanonicalization() + */ + public Canonicalization getSignedInfoCanonicalization() { + return signedInfoCanonicalization; + } + + /** + * Sets the canonicalization method to use for the SignedInfo object. + * + * @param signedInfoCanonicalization The canonicalization method to set. + */ + public void setSignedInfoCanonicalization(Canonicalization signedInfoCanonicalization) { + this.signedInfoCanonicalization = signedInfoCanonicalization; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignedProperties() + */ + public List getSignedProperties() { + return signedProperties; + } + + /** + * Set the signed properties. + * + * @param signedProperties The signed properties to set. + */ + public void setSignedProperties(List signedProperties) { + this.signedProperties = signedProperties; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#isSecurityLayerConform() + */ + public boolean isSecurityLayerConform() { + return securityLayerConform; + } + + /** + * Sets the security layer conformity. + * + * @param securityLayerConform <code>true</code>, if the created signature + * is to be conform to the Security Layer specification. + */ + public void setSecurityLayerConform(boolean securityLayerConform) { + this.securityLayerConform = securityLayerConform; + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureID() + */ + public String getSignatureID() { + return signatureIDGenerator.uniqueId(); + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSecurityLayerManifestID() + */ + public String getSecurityLayerManifestID() { + return manifestIDGenerator.uniqueId(); + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getDsigManifestID() + */ + public String getDsigManifestID() { + return dsigManifestIDGenerator.uniqueId(); + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignedPropertiesID() + */ + public String getSignedPropertiesID() { + return propertyIDGenerator.uniqueId(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureInsertionLocationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureInsertionLocationImpl.java new file mode 100644 index 000000000..d55f61303 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureInsertionLocationImpl.java @@ -0,0 +1,45 @@ +package at.gv.egovernment.moa.spss.server.iaik.xmlsign; + +import iaik.server.modules.xmlsign.XMLSignatureInsertionLocation; + +/** + * An object giving the location of where the signature will be + * inserted into the parent element. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureInsertionLocationImpl + implements XMLSignatureInsertionLocation { + + /** Where to put the signature into the signature parent element. */ + private int signatureChildIndex; + + /** + * Create a new <code>XMLSignatureInsertLocationImpl</code>. + * + * @param signatureChildIndex The position index at which to append the + * signature to the parent element. + */ + public XMLSignatureInsertionLocationImpl(int signatureChildIndex) { + setSignatureChildIndex(signatureChildIndex); + } + + /** + * @see iaik.server.modules.xmlsign.XMLSignatureInsertionLocation#getSignatureChildIndex() + */ + public int getSignatureChildIndex() { + return signatureChildIndex; + } + + /** + * Sets the position index at which to append the signature to the parent + * element. + * + * @param signatureChildIndex The position index to set. + */ + public void setSignatureChildIndex(int signatureChildIndex) { + this.signatureChildIndex = signatureChildIndex; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlverify/XMLSignatureVerificationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlverify/XMLSignatureVerificationProfileImpl.java new file mode 100644 index 000000000..216596dc3 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlverify/XMLSignatureVerificationProfileImpl.java @@ -0,0 +1,131 @@ +package at.gv.egovernment.moa.spss.server.iaik.xmlverify; + +import java.util.List; + +import iaik.pki.PKIProfile; +import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile; + +/** + * An object providing auxiliary information for verifying an XML signature. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureVerificationProfileImpl + implements XMLSignatureVerificationProfile { + + /** Whether to check the Security Layer manifest. */ + private boolean checkSecurityLayerManifest; + /** Whether to check the XMLDsig manifest. */ + private boolean checkXMLDsigManifests; + /** The profile for validating the signer certificate. */ + private PKIProfile certificateValidationProfile; + /** Supplements for the transformations. */ + private List transformationSupplements; + /** Whether to include hash input data in the response. */ + private boolean includeHashInputData; + /** Whether to include reference input data in the response. */ + private boolean includeReferenceInputData; + + /** + * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#checkSecurityLayerManifest() + */ + public boolean checkSecurityLayerManifest() { + return checkSecurityLayerManifest; + } + + /** + * Set whether to check the references in the Security Layer manifest. + * + * @param checkSecurityLayerManifest <code>true</code>, if the references + * in the Security Layer manifest must be checked. + */ + public void setCheckSecurityLayerManifest(boolean checkSecurityLayerManifest) { + this.checkSecurityLayerManifest = checkSecurityLayerManifest; + } + + /** + * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#checkXMLDsigManifests() + */ + public boolean checkXMLDsigManifests() { + return checkXMLDsigManifests; + } + + /** + * Sets whether to check the references of all XML Dsig manifests. + * + * @param checkXMLDSigManifests <code>true</code>, if the references in the + * XML Dsig manifest must be checked. + */ + public void setCheckXMLDsigManifests(boolean checkXMLDSigManifests) { + this.checkXMLDsigManifests = checkXMLDSigManifests; + } + + /** + * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#getCertificateValidationProfile() + */ + public PKIProfile getCertificateValidationProfile() { + return certificateValidationProfile; + } + + /** + * Sets the profile for validating the signer certificate. + * + * @param certificateValidationProfile The certificate validation profile to + * set. + */ + public void setCertificateValidationProfile(PKIProfile certificateValidationProfile) { + this.certificateValidationProfile = certificateValidationProfile; + } + + /** + * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#getTransformationSupplements() + */ + public List getTransformationSupplements() { + return transformationSupplements; + } + + /** + * Sets the transformation supplements. + * + * @param transformationSupplements The transformation supplements to set. + */ + public void setTransformationSupplements(List transformationSupplements) { + this.transformationSupplements = transformationSupplements; + } + + /** + * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#includeHashInputData() + */ + public boolean includeHashInputData() { + return includeHashInputData; + } + + /** + * Set whether to include the hash input data in the result. + * + * @param includeHashInputData If <code>true</code>, the hash input data + * will be returned in the result. + */ + public void setIncludeHashInputData(boolean includeHashInputData) { + this.includeHashInputData = includeHashInputData; + } + + /** + * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#includeReferenceInputData() + */ + public boolean includeReferenceInputData() { + return includeReferenceInputData; + } + + /** + * Set whether to include the reference input data in the result. + * + * @param includeReferenceInputData If <code>true</code>, the reference + * input data will be included in the result. + */ + public void setIncludeReferenceInputData(boolean includeReferenceInputData) { + this.includeReferenceInputData = includeReferenceInputData; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/init/ConfiguratorImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/init/ConfiguratorImpl.java new file mode 100644 index 000000000..caf17db66 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/init/ConfiguratorImpl.java @@ -0,0 +1,42 @@ +package at.gv.egovernment.moa.spss.server.init; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.Configurator; +import at.gv.egovernment.moa.spss.server.config.ConfigurationException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator; + +/** + * Default implementation of <code>Configurator</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ConfiguratorImpl extends Configurator { + /** whether the configuration has been initialized */ + private boolean initialized = false; + + public void init() throws MOAException { + if (!initialized) { + SystemInitializer.init(); + initialized = true; + } + } + + public void update() throws MOAException { + if (!initialized) { + return; + } + + try { + // reconfigure the system + ConfigurationProvider config = ConfigurationProvider.reload(); + new IaikConfigurator().configure(config); + } catch (MOAException e) { + throw e; + } catch (Throwable t) { + throw new ConfigurationException("", null, t); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java b/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java new file mode 100644 index 000000000..f968778d7 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java @@ -0,0 +1,122 @@ +package at.gv.egovernment.moa.spss.server.init; + +import java.io.IOException; +import java.security.Security; + +import javax.net.ssl.SSLSocketFactory; + +import iaik.ixsil.init.IXSILInit; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.logging.LoggingContext; +import at.gv.egovernment.moa.logging.LoggingContextManager; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator; +import at.gv.egovernment.moa.spss.server.logging.IaikLog; +import at.gv.egovernment.moa.spss.server.service.RevocationArchiveCleaner; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * MOA SP/SS web service initialization. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SystemInitializer { + /** Interval between archive cleanups in seconds */ + private static final long ARCHIVE_CLEANUP_INTERVAL = 60 * 60; // 1h + /** The MOA SP/SS logging hierarchy. */ + private static final String LOGGING_HIERARCHY = "moa.spss.server"; + /** Whether XML schema grammars have been initialized. */ + private static boolean grammarsInitialized = false; + + /** + * Initialize the MOA SP/SS webservice. + */ + public static void init() { + MessageProvider msg = MessageProvider.getInstance(); + ClassLoader cl = SystemInitializer.class.getClassLoader(); + Thread archiveCleaner; + + // set up the MOA SPSS logging hierarchy + Logger.setHierarchy(LOGGING_HIERARCHY); + + // set up a logging context for logging the startup + LoggingContextManager.getInstance().setLoggingContext( + new LoggingContext("startup")); + + // load some jsse classes so that the integrity of the jars can be verified + // before the iaik jce is installed as the security provider + // this workaround is only needed when sun jsse is used in conjunction with + // iaik-jce (on jdk1.3) + try { + cl.loadClass("javax.security.cert.Certificate"); // from jcert.jar + } catch (ClassNotFoundException e) { + Logger.warn(msg.getMessage("init.03", null), e); + } + + // set up SUN JSSE SSL + Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); + System.setProperty( + "java.protocol.handler.pkgs", + "com.sun.net.ssl.internal.www.protocol"); + SSLSocketFactory.getDefault(); + + // initialize preparsed Xerces grammar pool for faster XML + // parsing/validating + try { + if (!grammarsInitialized) { + Class clazz = SystemInitializer.class; + // preparse XML schema + DOMUtils.addSchemaToPool( + clazz.getResourceAsStream(Constants.XML_SCHEMA_LOCATION), + Constants.XML_NS_URI); + // preparse XMLDsig Filter2 schema + DOMUtils.addSchemaToPool( + clazz.getResourceAsStream(Constants.DSIG_FILTER2_SCHEMA_LOCATION), + Constants.DSIG_FILTER2_NS_URI); + // preparse XMLDsig schema + DOMUtils.addSchemaToPool( + clazz.getResourceAsStream(Constants.DSIG_SCHEMA_LOCATION), + Constants.DSIG_NS_URI); + // preparse MOA schema + DOMUtils.addSchemaToPool( + clazz.getResourceAsStream(Constants.MOA_SCHEMA_LOCATION), + Constants.MOA_NS_URI); + grammarsInitialized = true; + } + } catch (IOException e) { + Logger.warn(new LogMsg(msg.getMessage("init.04", null)), e); + } + + // initialize configuration + try { + ConfigurationProvider config = ConfigurationProvider.getInstance(); + new IaikConfigurator().configure(config); + Logger.info(new LogMsg(msg.getMessage("init.01", null))); + } catch (MOAException e) { + Logger.fatal(new LogMsg(msg.getMessage("init.00", null)), e); + } + + // set IXSIL debug output + IXSILInit.setPrintDebugLog( + Logger.isDebugEnabled(IaikLog.IAIK_LOG_HIERARCHY)); + + // start the archive cleanup thread + archiveCleaner = + new Thread(new RevocationArchiveCleaner(ARCHIVE_CLEANUP_INTERVAL)); + archiveCleaner.setName("RevocationArchiveCleaner"); + archiveCleaner.setDaemon(true); + archiveCleaner.setPriority(Thread.MIN_PRIORITY); + archiveCleaner.start(); + + // unset the startup logging context + LoggingContextManager.getInstance().setLoggingContext(null); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java new file mode 100644 index 000000000..33b924e2b --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java @@ -0,0 +1,207 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import iaik.IAIKException; +import iaik.IAIKRuntimeException; +import iaik.server.modules.cmsverify.CMSSignatureVerificationModule; +import iaik.server.modules.cmsverify.CMSSignatureVerificationModuleFactory; +import iaik.server.modules.cmsverify.CMSSignatureVerificationProfile; +import iaik.server.modules.cmsverify.CMSSignatureVerificationResult; + +import at.gv.egovernment.moa.logging.LoggingContext; +import at.gv.egovernment.moa.logging.LoggingContextManager; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContentExcplicit; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSContentReference; +import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.server.logging.IaikLog; +import at.gv.egovernment.moa.spss.server.logging.TransactionId; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; + +/** + * A class providing an interface to the + * <code>CMSSignatureVerificationModule</code>. + * + * This class performs the invocation of the + * <code>iaik.server.modules.cmsverify.CMSSignatureVerificationModule</code> + * from a <code>VerifyCMSSignatureRequest</code>. The result of the invocation + * is integrated into a <code>VerifyCMSSignatureResponse</code> returned. + * + * @author Patrick Peck + * @version $Id$ + */ +public class CMSSignatureVerificationInvoker { + + /** The single instance of this class. */ + private static CMSSignatureVerificationInvoker instance = null; + + /** + * Return the only instance of this class. + * + * @return The only instance of this class. + */ + public static synchronized CMSSignatureVerificationInvoker getInstance() { + if (instance == null) { + instance = new CMSSignatureVerificationInvoker(); + } + return instance; + } + + /** + * Create a new <code>CMSSignatureVerificationInvoker</code>. + * + * Protected to disallow multiple instances. + */ + protected CMSSignatureVerificationInvoker() { + } + + /** + * Verify a CMS signature. + * + * @param request The <code>VerifyCMSSignatureRequest</code> containing the + * CMS signature, as well as additional data needed for verification. + * @return Element A <code>VerifyCMSSignatureResponse</code> containing the + * answer to the <code>VerifyCMSSignatureRequest</code>. + * @throws MOAException An error occurred while processing the request. + */ + public VerifyCMSSignatureResponse verifyCMSSignature(VerifyCMSSignatureRequest request) + throws MOAException { + CMSSignatureVerificationProfileFactory profileFactory = + new CMSSignatureVerificationProfileFactory(request); + VerifyCMSSignatureResponseBuilder responseBuilder = + new VerifyCMSSignatureResponseBuilder(); + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + LoggingContext loggingCtx = + LoggingContextManager.getInstance().getLoggingContext(); + InputStream signature; + InputStream signedContent; + CMSSignatureVerificationProfile profile; + Date signingTime; + List results; + CMSSignatureVerificationResult result; + int[] signatories; + InputStream input; + byte[] buf = new byte[256]; + + // get the signature + signature = request.getCMSSignature(); + + // get the signed content + signedContent = getSignedContent(request); + + // build the profile + profile = profileFactory.createProfile(); + + // get the signing time + signingTime = request.getDateTime(); + + // verify the signature + try { + CMSSignatureVerificationModule module = + CMSSignatureVerificationModuleFactory.getInstance(); + + module.setLog(new IaikLog(loggingCtx.getNodeID())); + + module.init( + signature, + signedContent, + profile, + new TransactionId(context.getTransactionID())); + input = module.getInputStream(); + + while (input.read(buf) > 0); + results = module.verifySignature(signingTime); + } catch (IAIKException e) { + MOAException moaException = IaikExceptionMapper.getInstance().map(e); + throw moaException; + } catch (IAIKRuntimeException e) { + MOAException moaException = IaikExceptionMapper.getInstance().map(e); + throw moaException; + } catch (IOException e) { + throw new MOAApplicationException("2244", null, e); + } + + // build the response: for each signatory add the result to the response + signatories = request.getSignatories(); + if (signatories == VerifyCMSSignatureRequest.ALL_SIGNATORIES) { + Iterator resultIter; + + for (resultIter = results.iterator(); resultIter.hasNext();) { + result = (CMSSignatureVerificationResult) resultIter.next(); + responseBuilder.addResult(result); + } + } else { + int i; + + for (i = 0; i < signatories.length; i++) { + int sigIndex = signatories[i] - 1; + + try { + result = + (CMSSignatureVerificationResult) results.get(signatories[i] - 1); + responseBuilder.addResult(result); + } catch (IndexOutOfBoundsException e) { + throw new MOAApplicationException( + "2249", + new Object[] { new Integer(sigIndex)}); + } + } + } + + return responseBuilder.getResponse(); + } + + /** + * Get the signed content contained either in the request itself or given as a + * reference to external data. + * + * @param request The <code>VerifyCMSSignatureRequest</code> containing the + * signed content (or the reference to the signed content). + * @return InputStream A stream providing the signed content data, or + * <code>null</code> if no signed content was provided with the request. + * @throws MOAApplicationException An error occurred building the stream. + */ + private InputStream getSignedContent(VerifyCMSSignatureRequest request) + throws MOAApplicationException { + + CMSDataObject dataObj; + CMSContent content; + + // select the Content element + dataObj = request.getDataObject(); + if (dataObj == null) { + return null; + } + content = dataObj.getContent(); + + // build the content data + switch (content.getContentType()) { + case CMSContent.EXPLICIT_CONTENT : + return ((CMSContentExcplicit) content).getBinaryContent(); + case CMSContent.REFERENCE_CONTENT : + String reference = ((CMSContentReference) content).getReference(); + if (!"".equals(reference)) { + ExternalURIResolver resolver = new ExternalURIResolver(); + return resolver.resolve(reference); + } else { + return null; + } + default : + return null; + } + + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java new file mode 100644 index 000000000..442921850 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java @@ -0,0 +1,61 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import iaik.server.modules.cmsverify.CMSSignatureVerificationProfile; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.cmsverify.CMSSignatureVerificationProfileImpl; +import at.gv.egovernment.moa.spss.server.iaik.pki.PKIProfileImpl; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; + +/** + * A factory to create a <code>CMSSignatureVerificationProfile</code> from a + * <code>VerifyCMSSignatureRequest</code> and the current MOA configuration + * data. + * + * @author Patrick Peck + * @version $Id$ + */ +public class CMSSignatureVerificationProfileFactory { + + /** The <code>VerifyCMSSignatureRequest</code> to draw profile data from. */ + private VerifyCMSSignatureRequest request; + + /** + * Create a new <code>CMSSignatureVerificationProfileFactory</code>. + * + * @param request The <code>VerifyCMSSignatureRequest</code> to draw profile + * data from. + */ + public CMSSignatureVerificationProfileFactory(VerifyCMSSignatureRequest request) { + this.request = request; + } + + /** + * Create a <code>CMSSignatureVerificationProfile</code> from the given + * request and the current MOA configuration. + * + * @return The <code>CMSSignatureVerificationProfile</code> for the + * <code>request</code>, based on the current configuration. + * @throws MOAException An error occurred creating the profile. + */ + public CMSSignatureVerificationProfile createProfile() + throws MOAException { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + CMSSignatureVerificationProfileImpl profile = + new CMSSignatureVerificationProfileImpl(); + String trustProfileID; + + // set the certificate validation profile + trustProfileID = request.getTrustProfileId(); + profile.setCertificateValidationProfile( + new PKIProfileImpl(config, trustProfileID)); + + return profile; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java new file mode 100644 index 000000000..6302cadfd --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java @@ -0,0 +1,71 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.SignatureEnvironmentResponse; + +/** + * A class to build a <code>CreateXMLSignatureResponse</code>. + * + * <p>The methods <code>addSignature()</code> and <code>addError()</code> may be + * called in any combination to add <code>SignatureEnvironment</code> and + * <code>ErrorResponse</code> elements to the response. One of these functions + * must be called at least once to produce a + * <code>CreateXMLSignatureResponse</code>.</p> + * + * <p>The <code>getResponseElement()</code> method then returns the + * <code>CreateXMLSignatureResponse</code> built so far.</p> + * + * @author Patrick Peck + * @version $Id$ + */ +public class CreateXMLSignatureResponseBuilder { + + /** The <code>SPSSFactory</code> for creating API objects. */ + private SPSSFactory factory = SPSSFactory.getInstance(); + /** The elements to add to the response. */ + private List responseElements = new ArrayList(); + + /** + * Get the <code>CreateXMLSignatureResponse</code> built so far. + * + * @return The <code>CreateXMLSignatureResponse</code> built so far. + */ + public CreateXMLSignatureResponse getResponse() { + return factory.createCreateXMLSignatureResponse(responseElements); + } + + /** + * Add a <code>SignatureEnvironment</code> element to the response. + * + * @param signatureEnvironment The content to put under the + * <code>SignatureEnvironment</code> element. This should either be a + * <code>dsig:Signature</code> element (in case of a detached signature) or + * the signature environment containing the signature (in case of + * an enveloping signature). + */ + public void addSignatureEnvironment(Element signatureEnvironment) { + SignatureEnvironmentResponse responseElement = + factory.createSignatureEnvironmentResponse(signatureEnvironment); + responseElements.add(responseElement); + } + + /** + * Add a <code>ErrorResponse</code> element to the response. + * + * @param errorCode The error code. + * @param info Additional information about the error. + */ + public void addError(String errorCode, String info) { + ErrorResponse errorResponse = + factory.createErrorResponse(Integer.parseInt(errorCode), info); + responseElements.add(errorResponse); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java new file mode 100644 index 000000000..32c81dc07 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java @@ -0,0 +1,717 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.xml.sax.EntityResolver; +import org.xml.sax.SAXException; + +import iaik.ixsil.util.URI; +import iaik.ixsil.util.XPointerReferenceResolver; +import iaik.server.modules.xml.DataObject; +import iaik.server.modules.xml.XMLDataObject; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.EntityResolverChain; +import at.gv.egovernment.moa.util.MOAEntityResolver; +import at.gv.egovernment.moa.util.MOAErrorHandler; +import at.gv.egovernment.moa.util.StreamEntityResolver; +import at.gv.egovernment.moa.util.StreamUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.ContentBinary; +import at.gv.egovernment.moa.spss.api.common.ContentXML; +import at.gv.egovernment.moa.spss.api.common.MetaInfo; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterBinary; +import at.gv.egovernment.moa.spss.server.iaik.xml.ByteArrayDataObjectImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.ByteStreamDataObjectImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.DataObjectImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.XMLDataObjectImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.XMLNodeListDataObjectImpl; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A class to create <code>DataObject</code>s contained in different + * locations of the MOA XML request format. + * + * @author Patrick Peck + * @version $Id$ + */ +public class DataObjectFactory { + + /** The single instance of this class. */ + private static DataObjectFactory instance = null; + + /** + * Return the only instance of this class. + * + * @return The only instance of this class. + */ + public static synchronized DataObjectFactory getInstance() { + if (instance == null) { + instance = new DataObjectFactory(); + } + return instance; + } + + /** + * Create a new <code>DataObjectFactory</code>. + * + * Protected to disallow multiple instances. + */ + protected DataObjectFactory() { + } + + /** + * Return the signature environment, i.e., the root element of the + * document, into which the signature will be inserted (if created) or which + * contains the signature (if verified). + * + * @param content The <code>Content</code> object containing the signature + * environment. + * @param supplements Additional schema or DTD information. + * @return The signature environment or <code>null</code>, if no + * signature environment exists. + * @throws MOASystemException A system error occurred building the signature + * environment (see message for details). + * @throws MOAApplicationException An error occurred building the signature + * environment (see message for details). + */ + public XMLDataObject createSignatureEnvironment( + Content content, + List supplements) + throws MOASystemException, MOAApplicationException { + + String reference = content.getReference(); + EntityResolver entityResolver; + byte[] contentBytes; + + // check for content and reference not being set at the same time + checkAllowContentAndReference(content, false); + + // build the EntityResolver for validating parsing + if (supplements == null || supplements.isEmpty()) { + entityResolver = new MOAEntityResolver(); + } else { + EntityResolverChain chain = new EntityResolverChain(); + + chain.addEntityResolver(buildSupplementEntityResolver(supplements)); + chain.addEntityResolver(new MOAEntityResolver()); + entityResolver = chain; + } + + // convert the content into a byte array + try { + switch (content.getContentType()) { + case Content.BINARY_CONTENT : + { + InputStream is = ((ContentBinary) content).getBinaryContent(); + contentBytes = StreamUtils.readStream(is); + break; + } + case Content.REFERENCE_CONTENT : + { + ExternalURIResolver uriResolver = new ExternalURIResolver(); + InputStream is = uriResolver.resolve(reference); + contentBytes = StreamUtils.readStream(is); + break; + } + case Content.XML_CONTENT : + { + Element element = + checkForSingleElement(((ContentXML) content).getXMLContent()); + contentBytes = DOMUtils.serializeNode(element, "UTF-8"); + break; + } + default : + contentBytes = null; // this will not happen + } + } catch (MOAApplicationException e) { + throw e; + } catch (Exception e) { + throw new MOAApplicationException("2219", null); + } + + // try to parse validating + try { + ByteArrayInputStream is = new ByteArrayInputStream(contentBytes); + Document doc = + DOMUtils.parseDocument( + is, + true, + Constants.ALL_SCHEMA_LOCATIONS, + null, + entityResolver, + new MOAErrorHandler()); + + return new XMLDataObjectImpl(doc.getDocumentElement()); + } catch (Exception e) { + // never mind, we'll try non-validating + MessageProvider msg = MessageProvider.getInstance(); + Logger.info(new LogMsg(msg.getMessage("invoker.00", null))); + } + + // try to parse non-validating + try { + ByteArrayInputStream is = new ByteArrayInputStream(contentBytes); + Document doc = DOMUtils.parseDocument(is, false, null, null); + return new XMLDataObjectImpl(doc.getDocumentElement()); + } catch (Exception e) { + throw new MOAApplicationException("2218", null); + } + } + + /** + * Create an <code>XMLDataObject</code> from the given signature environment. + * + * @param signatureEnvironment The signature environment contained in the + * result. + * @param uri The URI identifying the data. This must be either the empty + * URI, an URI starting with <code>"#xpointer"</code>, <code>"#xmlns"</code> + * or <code>"#element"</code>; or an URI starting with <code>"#"</code> and + * followed by an element ID. + * @param referenceID The reference ID to set for the data object. + * @return A data object containing the signature environment. + */ + public DataObject createFromSignatureEnvironment( + Element signatureEnvironment, + String uri, + String referenceID) + throws MOAApplicationException { + + DataObjectImpl dataObject = null; + + if ("".equals(uri)) { + dataObject = new XMLDataObjectImpl(signatureEnvironment); + } else if ( + uri.startsWith("#xpointer") + || uri.startsWith("#xmlns") + || uri.startsWith("#element")) { + try { + XPointerReferenceResolver resolver = new XPointerReferenceResolver(); + URI uriObj = new URI(uri); + NodeList nodes = + resolver.resolveForest( + uriObj, + signatureEnvironment.getOwnerDocument(), + null); + dataObject = new XMLNodeListDataObjectImpl(nodes); + } catch (Exception e) { + throw new MOAApplicationException("2237", new Object[] { uri }); + } + } else if (uri.startsWith("#")) { + String id = uri.substring(1); + Element refElem = + signatureEnvironment.getOwnerDocument().getElementById(id); + + if (refElem == null) { + throw new MOAApplicationException("2237", new Object[] { id }); + } + dataObject = new XMLDataObjectImpl(refElem); + } + + dataObject.setReferenceID(referenceID); + dataObject.setURI(uri); + + return dataObject; + } + + /** + * Build a <code>StreamEntityResolver</code> from a <code>List</code> of + * supplements. + * + * @param supplements The supplements, given as + * <code>XMLDataObjectAssociation</code>s. + * @return A <code>StreamEntityResolver</code> mapping the supplements by + * their reference URI to an <code>InputStream</code> of their respective + * content. + */ + private static StreamEntityResolver buildSupplementEntityResolver(List supplements) { + Map entities = new HashMap(); + Iterator iter; + + for (iter = supplements.iterator(); iter.hasNext();) { + XMLDataObjectAssociation supplement = + (XMLDataObjectAssociation) iter.next(); + Content content = supplement.getContent(); + String reference = content.getReference(); + + switch (content.getContentType()) { + case Content.BINARY_CONTENT : + entities.put(reference, ((ContentBinary) content).getBinaryContent()); + break; + case Content.XML_CONTENT : + // serialize the first element node that is found in the supplement + // and make it available as a stream + NodeList nodes = ((ContentXML) content).getXMLContent(); + int i = 0; + + // find the first element node + while (i < nodes.getLength() + && nodes.item(i).getNodeType() != Node.ELEMENT_NODE) + i++; + + // serialize the node + if (i < nodes.getLength()) { + try { + byte[] serialized = + DOMUtils.serializeNode(nodes.item(i), "UTF-8"); + entities.put(reference, new ByteArrayInputStream(serialized)); + } catch (Exception e) { + // serializing the element failed - just don't put it in the map + } + } + + break; + } + } + + return new StreamEntityResolver(entities); + } + + /** + * Create a <code>DataObject</code> from a <code>Content</code> object. + * + * @param content The <code>Content</code> object containing the data. + * @param referenceID The reference ID to set in the resulting + * <code>DataObject</code>. May be <code>null</code>. + * @param allowContentAndReference If <code>true</code>, then + * <code>content</code> is allowed to contain both a <code>Reference</code> + * attribute and content. Otherwise, either a <code>Reference</code> + * attribute or content must be set. + * @param binaryAsXml If <code>true</code>, a content child given as + * <code>Base64Content</code> must contain XML data. + * @param xmlAsNodeList If <code>true</code>, the children of a + * <code>XMLContent</code> child element are returned as a + * <code>XMLNodeListDataObject</code>. Otherwise, <code>XMLContent</code> may + * only contain a single child node, which must be an element and which is + * returned as an <code>XMLDataObject</code>. + * @param referenceAsXml If <code>true</code>, then content loaded from the + * URI given as the <code>Reference</code> attribute must be XML data. + * If <code>false</code>, an attempt is made to parse the data as XML and + * return an <code>XMLDataObject</code> but if this fails, a + * <code>BinaryDataObject</code> is returned containing a byte stream to the + * data. + * @return A <code>DataObject</code> representing the data in + * <code>content</code>. If <code>base64AsXml==true</code> and + * <code>xmlAsNodeList==false</code> and <code>referenceAsXml==true</code>, + * then the result can safely be cast to an <code>XMLDataObject</code>. + * @throws MOASystemException An error indicating an internal problem. See the + * wrapped exception for details. + * @throws MOAApplicationException An error occurred handling the content + * (probably while opening a reference or parsing the data). See the wrapped + * exception for details. + */ + public DataObject createFromContentOptionalRefType( + Content content, + String referenceID, + boolean allowContentAndReference, + boolean binaryAsXml, + boolean xmlAsNodeList, + boolean referenceAsXml) + throws MOASystemException, MOAApplicationException { + + String reference = content.getReference(); + DataObjectImpl dataObject = null; + + checkAllowContentAndReference(content, allowContentAndReference); + + // ok, build the data object; use content first, if available + switch (content.getContentType()) { + case Content.XML_CONTENT : + ContentXML contentXml = (ContentXML) content; + dataObject = createFromXmlContent(contentXml, xmlAsNodeList); + break; + case Content.BINARY_CONTENT : + ContentBinary contentBinary = (ContentBinary) content; + dataObject = createFromBinaryContent(contentBinary, binaryAsXml, false); + break; + case Content.REFERENCE_CONTENT : + dataObject = createFromURIImpl(reference, referenceAsXml); + break; + } + + // set URI and reference ID + dataObject.setURI(content.getReference()); + dataObject.setReferenceID(referenceID); + + return dataObject; + } + + /** + * Check, if content and reference URIs are allowed in the content an throw + * an exception if an illegal combination of the two occurs. + * + * @param content The <code>Content</code> to check. + * @param allowContentAndReference Whether explicit content and a reference + * are allowed at the same time. + * @throws MOAApplicationException If <code>allowContentAndRefernece</code> + * is <code>false</code> and both explicit content and reference are set, + * an exception is thrown. + */ + private static void checkAllowContentAndReference( + Content content, + boolean allowContentAndReference) + throws MOAApplicationException { + String reference = content.getReference(); + + // check for content and reference not being set + if (content.getContentType() == Content.REFERENCE_CONTENT + && reference == null) { + String errorCode = allowContentAndReference ? "1111" : "1110"; + throw new MOAApplicationException(errorCode, null); + } + + // if we only allow either content or reference being set at once, check + if (!allowContentAndReference + && (content.getContentType() != Content.REFERENCE_CONTENT) + && (reference != null)) { + throw new MOAApplicationException("1110", null); + } + } + + /** + * Create a <code>DataObject</code> from a + * <code>XMLDataObjectAssociation</code> object. + * + * @param xmlDataObjAssoc The <code>XMLDataObjectAssociation</code> object. + * @param xmlContentAllowed Whether the content contained in the + * <code>xmlDataObjAssoc</code> is allowed to be of type + * <code>XML_CONTENT</code>. + * @param binaryContentRepeatable If binary content must be provided as a + * <code>DataObject</code> that can be read multiple times. + * @return A <code>DataObject</code> representing the data in + * <code>xmlDataObjAssoc</code>. + * @throws MOASystemException An error indicating an internal problem. See the + * wrapped exception for details. + * @throws MOAApplicationException An error occurred handling the content + * (probably while parsing the data). See the wrapped exception for details. + */ + public DataObject createFromXmlDataObjectAssociation( + XMLDataObjectAssociation xmlDataObjAssoc, + boolean xmlContentAllowed, + boolean binaryContentRepeatable) + throws MOASystemException, MOAApplicationException { + + Content content = xmlDataObjAssoc.getContent(); + MetaInfo metaInfo = xmlDataObjAssoc.getMetaInfo(); + String mimeType = metaInfo != null ? metaInfo.getMimeType() : null; + DataObjectImpl dataObject = null; + + switch (content.getContentType()) { + case Content.XML_CONTENT : + if (xmlContentAllowed) { + dataObject = createFromXmlContent((ContentXML) content, true); + } else { + throw new MOAApplicationException("2280", null); + } + break; + case Content.BINARY_CONTENT : + dataObject = + createFromBinaryContent( + (ContentBinary) content, + false, + binaryContentRepeatable); + break; + } + + dataObject.setURI(content.getReference()); + dataObject.setMimeType(mimeType); + return dataObject; + } + + /** + * Create a <code>DataObject</code> from a <code>TransformParameter</code> + * object. + * + * @param transformParameter The <code>TransformParameter</code> object + * containing the data. + * @return A <code>DataObject</code> representing the data in + * <code>root</code>. + * @throws MOASystemException An error indicating an internal problem. See the + * wrapped exception for details. + * @throws MOAApplicationException An error occurred handling the content + * (probably while opening a reference or parsing the data). See the wrapped + * exception for details. + */ + public DataObject createFromTransformParameter(TransformParameter transformParameter) + throws MOASystemException, MOAApplicationException { + + DataObjectImpl dataObject; + + switch (transformParameter.getTransformParameterType()) { + case TransformParameter.BINARY_TRANSFORMPARAMETER : + TransformParameterBinary tpBinary = + (TransformParameterBinary) transformParameter; + + try { + //dataObject = new ByteArrayDataObjectImpl(Base64Utils.encode(tpBinary.getBinaryContent())); + dataObject = + new ByteArrayDataObjectImpl( + StreamUtils.readStream(tpBinary.getBinaryContent())); + } catch (Exception e) { + return null; + } + //dataObject = new ByteStreamDataObjectImpl(tpBinary.getBinaryContent()); + break; + default : + // resolve uri and build the content + ExternalURIResolver resolver = new ExternalURIResolver(); + InputStream is = resolver.resolve(transformParameter.getURI()); + String contentType = resolver.getContentType(); + dataObject = new ByteStreamDataObjectImpl(is); + dataObject.setMimeType(contentType); + break; + } + + dataObject.setURI(transformParameter.getURI()); + + return dataObject; + } + + /** + * Create a <code>DataObject</code> from data located at the given URI. + * + * @param uri The <code>URI</code> where the data is located. This method uses + * an <code>ExternalURIResolver</code> to resolve URIs. + * @param asXml If <code>true</code>, a <code>DataObject</code> is only + * returned, if the content consists of XML data. If it does not consist of + * XML data, an <code>MOAApplicationException</code> will be thrown. If this + * parameter is <code>false</code> and the content consists of XML data, this + * method will still attempt to parse it. + * @return The <code>DataObject</code> contained at the URI. + * @throws MOASystemException A system error parsing the XML content. + * @throws MOAApplicationException An error occurred on opening, reading or + * parsing the data behind the URI. + */ + public DataObject createFromURI(String uri, boolean asXml) + throws MOASystemException, MOAApplicationException { + return createFromURIImpl(uri, asXml); + } + + /** + * Create a <code>DataObject</code> from data located at the given URI. + * + * @param uri The <code>URI</code> where the data is located. This method uses + * an <code>ExternalURIResolver</code> to resolve URIs. + * @param asXml If <code>true</code>, a <code>DataObject</code> is only + * returned, if the content consists of XML data. If it does not consist of + * XML data, an <code>MOAApplicationException</code> will be thrown. If this + * parameter is <code>false</code> and the content type is detected as being + * XML data, this method will still attemt to parse it. + * @return The <code>DataObject</code> contained at the URI. + * @throws MOASystemException A system error parsing the XML content. + * @throws MOAApplicationException An error occurred on opening, reading or + * parsing the data behind the URI. + */ + private DataObjectImpl createFromURIImpl(String uri, boolean asXml) + throws MOASystemException, MOAApplicationException { + + ExternalURIResolver resolver = new ExternalURIResolver(); + InputStream is = resolver.resolve(uri); + String contentType = resolver.getContentType(); + DataObjectImpl dataObject; + + // read the content + if (contentType != null && contentTypeIsXml(contentType)) { + Document doc; + + if (asXml) { + try { + // try parsing non-validating: this has to succeed or we + // bail out by throwing an exception + is = resolver.resolve(uri); + doc = DOMUtils.parseDocument(is, false, null, null); + dataObject = new XMLDataObjectImpl(doc.getDocumentElement()); + } catch (ParserConfigurationException e) { + throw new MOASystemException("1106", null, e); + } catch (SAXException e) { + throw new MOAApplicationException("2209", null, e); + } catch (IOException e) { + throw new MOAApplicationException("2210", null, e); + } + } else { + try { + // try parsing non-validating: need not succeed + is = resolver.resolve(uri); + doc = DOMUtils.parseDocument(is, false, null, null); + dataObject = new XMLDataObjectImpl(doc.getDocumentElement()); + } catch (Exception e) { + // this is the last chance: return the data as a byte stream + is = resolver.resolve(uri); + dataObject = new ByteStreamDataObjectImpl(is); + } + } + } else if (asXml) { + // if we need XML data, we're in the wrong place here + throw new MOAApplicationException("2211", new Object[] { uri }); + } else { + // content is binary: make it available as a binary input stream + dataObject = new ByteStreamDataObjectImpl(is); + } + + dataObject.setMimeType(contentType); + dataObject.setURI(uri); + + return dataObject; + } + + /** + * Determine whether the content type is XML. + * + * Content types recognized as XML start with <code>text/xml</code> and + * <code>application/xml</code>. + * + * @param contentType The content MIME type. + * @return boolean If <code>true</code>, the content type is XML, otherwise + * not. + */ + private static boolean contentTypeIsXml(String contentType) { + return contentType.startsWith("text/xml") + || (contentType.startsWith("application/xml")); + } + + /** + * Create a <code>DataObject</code> from a <code>ContentXML</code> object. + * + * @param xmlContent The <code>ContentXML</code> object from + * which the <code>DataObject</code> is to be built. + * @param xmlAsNodeList If <code>true</code>, the children of + * <code>xmlContent</code> are returned as a + * <code>XMLNodeListDataObject</code>. Otherwise, + * <code>xmlContent</code> may only contain a single child node, which must be + * an element and which is returned as an <code>XMLDataObject</code>. + * @return A <code>DataObject</code> representing the XML content in + * <code>xmlContent</code>. + * @throws MOAApplicationException If <code>xmlAsNodeList</code> is + * <code>false</code> and <code>xmlContent</code> does not have a single child + * element. + */ + private DataObjectImpl createFromXmlContent( + ContentXML xmlContent, + boolean xmlAsNodeList) + throws MOAApplicationException { + + DataObjectImpl dataObject; + + if (xmlAsNodeList) { + dataObject = new XMLNodeListDataObjectImpl(xmlContent.getXMLContent()); + } else { + NodeList nodes = xmlContent.getXMLContent(); + Element element = checkForSingleElement(nodes); + + // build the XMLDataObject + dataObject = new XMLDataObjectImpl(element); + } + return dataObject; + } + + /** + * Check, that the given <code>NodeList</code> contains a single DOM element + * node and return it, otherwise throw an exception. + * + * @param nodes The <code>NodeList</code> to check for a single element. + * @return The single element contained in <code>nodes</code>. + * @throws MOAApplicationException Thrown, if <code>nodes</code> does not + * contain exactly 1 element node. + */ + private Element checkForSingleElement(NodeList nodes) + throws MOAApplicationException { + + Element element = null; + int i; + + // check for a single element node + for (i = 0; i < nodes.getLength(); i++) { + if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE) { + if (element == null) { + element = (Element) nodes.item(i); + } else { + throw new MOAApplicationException("1109", null); + } + } + } + + // return the element node + if (element == null) { + throw new MOAApplicationException("1107", null); + } else { + return element; + } + } + + /** + * Create a <code>DataObject</code> from a <code>ContentBinary</code> object. + * + * @param binaryContent The <code>ContentBinary</code> object containing the + * data. + * @param asXml If <code>true</code>, <code>binaryContent</code> must + * contain XML data. Otherwise, a <code>BinaryDataObject</code> will be + * returned containing a byte stream to the decoded Base64 data. + * @param repeatable If multiple calls to <code>getInputStream()</code> must + * repeatedly return the content of the data object. + * @return A <code>DataObject</code> representing the content contained in + * <code>binaryContent</code>. + * @throws MOASystemException An error indicating an internal problem. See the + * wrapped exception for details. + * @throws MOAApplicationException An error occurred handling the content + * (probably while parsing the data). See the wrapped exception for details. + */ + private DataObjectImpl createFromBinaryContent( + ContentBinary binaryContent, + boolean asXml, + boolean repeatable) + throws MOASystemException, MOAApplicationException { + + InputStream byteStream = binaryContent.getBinaryContent(); + DataObjectImpl dataObject; + + if (asXml) { + Document doc; + + try { + doc = DOMUtils.parseDocument(byteStream, false, null, null); + dataObject = new XMLDataObjectImpl(doc.getDocumentElement()); + } catch (ParserConfigurationException e) { + throw new MOASystemException("1106", null, e); + } catch (SAXException e) { + throw new MOAApplicationException("2209", null, e); + } catch (IOException e) { + throw new MOAApplicationException("2210", null, e); + } + } else { + if (repeatable) { + try { + dataObject = + new ByteArrayDataObjectImpl(StreamUtils.readStream(byteStream)); + } catch (IOException e) { + throw new MOAApplicationException("2210", null); + } + } else { + dataObject = new ByteStreamDataObjectImpl(byteStream); + } + } + + return dataObject; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java new file mode 100644 index 000000000..806b76409 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java @@ -0,0 +1,127 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import iaik.ixsil.exceptions.URIException; +import iaik.ixsil.util.URI; + +import at.gv.egovernment.moa.spss.MOAApplicationException; + +/** + * Resolve external URIs and provide them as a stream. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ExternalURIResolver { + + /** The MIME type of the content currently resolved. */ + private String contentType; + + /** + * Return a stream to data at the given URI. + * + * This method will try to open an <code>URLConnection</code> to the given + * URI. Access to the file system is disallowed. + * + * @param uriStr The URI to resolve. + * @return InputStream The data contained at the URI. + * @throws MOAApplicationException An error occurred resolving the URI (e.g., + * the URI is syntactically incorrect or the stream could not be opened). + */ + public InputStream resolve(String uriStr) throws MOAApplicationException { + URI uri; + URL url; + URLConnection connection; + InputStream is; + + // build the URI + try { + uri = new URI(uriStr); + } catch (URIException e) { + throw new MOAApplicationException("2207", new Object[] { uriStr }); + } + + // disallow access to local file system + if ("".equals(uri.getScheme()) || "file".equals(uri.getScheme())) { + throw new MOAApplicationException("2213", new Object[] { uriStr }); + } + + // convert URI to URL + try { + // create the URL + url = new URL(uriStr); + } catch (MalformedURLException e) { + throw new MOAApplicationException("2214", new Object[] { uriStr }); + } + + // build the URLConnection + try { + connection = url.openConnection(); + if ("http".equals(url.getProtocol())) { + HttpURLConnection httpConnection = (HttpURLConnection) connection; + + httpConnection.connect(); + if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { + throw new MOAApplicationException("2208", new Object[] { uri }); + } + } else if ("https".equals(url.getProtocol())) { + /* + * this doesn't work because of some interaction between the IAIK + * JCE and Sun JSSE that results in an "Invalid AVA format" exception + */ + + /* + HttpsURLConnection httpsConnection = (HttpsURLConnection) connection; + InputStream trustStore = + getClass().getResourceAsStream(DEFAULT_TRUST_STORE); + SSLSocketFactory factory = + SSLUtils.getSSLSocketFactory("jks", trustStore, "changeit"); + httpsConnection.setSSLSocketFactory(factory); + httpsConnection.connect(); + if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { + throw new MOAApplicationException("2208", new Object[] { uri }); + } + */ + connection.connect(); + } else { + connection.connect(); + } + is = connection.getInputStream(); + } catch (IOException e) { + throw new MOAApplicationException("2208", new Object[] { uri }, e); + } /*catch (GeneralSecurityException e) { + throw new MOAApplicationException("2208", new Object[] { uri }, e); + }*/ + + // set the content type + setContentType(connection.getContentType()); + + return is; + } + + /** + * Set the content type of the data at the URI. + * + * @param contentType The content type to set. + */ + protected void setContentType(String contentType) { + this.contentType = contentType; + } + + /** + * Return the content type of the data detected at the URI from the previous + * call of <code>resolve()</code>. + * + * @return String The content type. + */ + public String getContentType() { + return contentType; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java new file mode 100644 index 000000000..60f573e5a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java @@ -0,0 +1,267 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + +import iaik.IAIKException; +import iaik.IAIKRuntimeException; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.MOASystemException; + + +/** + * Map an exception from the <code>iaik</code> namespace to a + * <code>MOAException</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class IaikExceptionMapper { + + /** The argument classes for <code>MOAException</code>s. */ + private static final Class[] CONSTRUCTOR_ARGS = + new Class[] { String.class, Object[].class, Throwable.class }; + /** The exception mapping, as an array. */ + private static final Object[][] MESSAGES = + { + { iaik.IAIKException.class, "9900", MOASystemException.class }, + { iaik.IAIKRuntimeException.class, "9901", MOASystemException.class }, + { iaik.server.modules.xmlsign.XMLSignatureCreationException.class, "2220", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.XMLSignatureCreationRuntimeException.class, "2220", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.InvalidKeyException.class, "2221", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.ManifestException.class, "2222", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.ReferenceException.class, "2223", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.HashUnavailableException.class, "2224", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.SignatureAlgorithmException.class, "2225", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.SignatureEmbeddingException.class, "2226", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.SignatureValueException.class, "2227", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.SignedPropertyException.class, "2228", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.SignerCertificateUnavailableException.class, "2229", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.SupplementException.class, "2230", MOAApplicationException.class }, + { iaik.server.modules.xmlsign.TransformationException.class, "2233", MOAApplicationException.class }, + { iaik.server.modules.cmsverify.CMSSignatureVerificationException.class, "2240", MOAApplicationException.class }, + { iaik.server.modules.cmsverify.CMSSignatureVerificationRuntimeException.class, "2240", MOAApplicationException.class }, + { iaik.server.modules.cmsverify.AlgorithmNotSupportedException.class, "2241", MOAApplicationException.class }, + { iaik.server.modules.cmsverify.CMSSignatureParsingException.class, "2242", MOAApplicationException.class }, + { iaik.server.modules.cmsverify.SignerCertificateUnavailableException.class, "2243", MOAApplicationException.class }, + { iaik.server.modules.cmsverify.CMSSignatureVerificationRuntimeException.class, "2247", MOAApplicationException.class }, + { iaik.server.modules.cmsverify.InitException.class, "2248", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.XMLSignatureVerificationException.class, "2240", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.XMLSignatureVerificationRuntimeException.class, "2240", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.AlgorithmNotSupportedException.class, "2241", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.ManifestException.class, "2262", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.PropertiesException.class, "2263", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.ReferenceException.class, "2264", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.HashUnavailableException.class, "2224", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.SignerCertificateUnavailableException.class, "2243", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.SupplementException.class, "2230", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.TransformationException.class, "2265", MOAApplicationException.class }, + { iaik.server.modules.xmlverify.TransformationParsingException.class, "2269", MOAApplicationException.class } + }; + + /** The single instance of this class. */ + private static IaikExceptionMapper instance; + /** The exception mapping, as a <code>Map</code> for fast lookup. */ + private Map messages = new HashMap(); + + /** + * Get the single instance of this class. + * + * @return The single instance of this class. + */ + public static synchronized IaikExceptionMapper getInstance() { + if (instance == null) { + instance = new IaikExceptionMapper(); + } + return instance; + } + + /** + * Create a new <code>IaikExceptionMapper</code>. + * + * Protected to disallow multple instances. + */ + protected IaikExceptionMapper() { + registerMessages(); + } + + /** + * Build the complete <code>IAIKException</code> to message code mapping. + */ + protected void registerMessages() { + int i; + + for (i = 0; i < MESSAGES.length; i++) { + registerMessage( + (Class) MESSAGES[i][0], + (String) MESSAGES[i][1], + (Class) MESSAGES[i][2]); + } + } + + /** + * Register a single <code>IAIKException</code> to message mapping. + * + * @param iaikExceptionClass An exception from the <code>iaik</code> package. + * @param messageId The corresponding error message id. + * @param moaExceptionClass The type of <code>MOAException</code> that the + * <code>IAIKException</code> is mapped to (usually + * <code>MOAApplicationException</code> or <code>MOASystemException</code>). + */ + protected void registerMessage( + Class iaikExceptionClass, + String messageId, + Class moaExceptionClass) { + + messages.put( + iaikExceptionClass, + new ExceptionMappingInfo(messageId, moaExceptionClass)); + } + + /** + * Map an <code>IAIKException</code> to a <code>MOAException</code>. + * + * @param iaikException The <code>IAIKException</code> to map. + * @return A <code>MOAException</code> containing the message for the + * given <code>IAIKException</code>. + */ + public MOAException map(IAIKException iaikException) { + return mapImpl(iaikException); + } + + /** + * Map an <code>IAIKRuntimeException</code> to a <code>MOAException</code>. + * + * @param iaikException The <code>IAIKException</code> to map. + * @return A <code>MOAException</code> containing the message for the + * given <code>IAIKRuntimeException</code>. + */ + public MOAException map(IAIKRuntimeException iaikException) { + return mapImpl(iaikException); + } + + /** + * Map an <code>IAIKException</code> or <code>IAIKRuntimeException</code> to a + * <code>MOAException</code>. + * + * @param iaikException The <code>IAIKException</code> or + * <code>IAIKRuntimeException</code> to map. + * @return A <code>MOAException</code> containing the message for the + * given <code>IAIKRuntimeException</code>. + */ + private MOAException mapImpl(Exception iaikException) { + MOAException moaException = createMoaException(iaikException); + + if (moaException == null) { + return new MOASystemException("9999", null, iaikException); + } + return moaException; + } + + /** + * Create a <code>MOAException</code> from a given <code>IAIKException</code> + * by looking it up in the mapping. + * + * @param iaikException The <code>IAIKException</code> to map. + * @return A <code>MOAException</code> with an error code corresponding to + * the given <code>IAIKException</code>. Returns <code>null</code>, if no + * mapping could be found. + */ + protected MOAException createMoaException(Exception iaikException) { + ExceptionMappingInfo info = lookupMessage(iaikException.getClass()); + Constructor constructor; + + if (info == null) { + return null; + } + + // instantiate the proper MOAException and return it + try { + constructor = + info.getMoaExceptionClass().getConstructor(CONSTRUCTOR_ARGS); + return (MOAException) constructor.newInstance( + new Object[] { + info.getMessageId(), + new Object[] { iaikException.getMessage()}, + iaikException }); + } catch (Exception e) { + return null; + } + } + + /** + * Recursively look up the message associated with an + * <code>IAIKException</code>. + * + * This method walks up the exception inheritance hierarchy until it finds a + * mapping. + * + * @param iaikExceptionClass The <code>IAIKException</code> to look up. + * @return Information about the message id and + * <code>MOAException</code> class that the <code>iaikExceptionClass</code> + * maps to. If no mapping could be found, <code>null</code> is returned. + */ + protected ExceptionMappingInfo lookupMessage(Class iaikExceptionClass) { + ExceptionMappingInfo info; + + // break if + if (iaikExceptionClass.equals(Exception.class)) { + return null; + } + + // look up the exception class + info = (ExceptionMappingInfo) messages.get(iaikExceptionClass); + if (info == null) { + return lookupMessage(iaikExceptionClass.getSuperclass()); + } + return info; + } + +} + +/** + * A class containing a mapping from an error message ID to a + * <code>MOAException</code> class. + * + * @author Patrick Peck + * @version $Id$ + */ +class ExceptionMappingInfo { + /** The message ID. */ + private String messageId; + /** The <code>MOAException</code> class. */ + private Class moaExceptionClass; + + /** + * Create a new <code>ExceptionMappingInfo</code>. + * + * @param messageId The message ID. + * @param moaExceptionClass The <code>MOAException</code> class. + */ + public ExceptionMappingInfo(String messageId, Class moaExceptionClass) { + this.messageId = messageId; + this.moaExceptionClass = moaExceptionClass; + } + + /** + * Return the message ID. + * + * @return The message ID. + */ + public String getMessageId() { + return messageId; + } + + /** + * Returns the <code>MOAException</code> class that the message ID maps to. + * + * @return The <code>MOAException</code> class. + */ + public Class getMoaExceptionClass() { + return moaExceptionClass; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java new file mode 100644 index 000000000..0c3b45539 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java @@ -0,0 +1,63 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.util.XPathException; +import at.gv.egovernment.moa.util.XPathUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.common.ElementSelector; + +/** + * Utility methods for invoking the IAIK MOA modules. + * + * @author Patrick Peck + * @version $Id$ + */ +public class InvokerUtils { + + /** + * Select the signature parent element. + * + * @param root The root DOM element which contains the signature parent + * element somewhere in its subtree. + * @param location The <code>ElementSelector</code> containing the XPath + * expression to select the signature parent element from the document. + * It is also contains the namespace prefix to URI mapping. + * @return Element The signature parent element. + * @throws MOAApplicationException An error occurred evaluating the + * <code>location</code>. + */ + public static Element evaluateSignatureLocation( + Element root, + ElementSelector location) + throws MOAApplicationException { + + NodeList nodes; + + try { + nodes = + XPathUtils.selectNodeList( + root, + location.getNamespaceDeclarations(), + location.getXPathExpression()); + } catch (XPathException e) { + throw new MOAApplicationException( + "2212", + new Object[] { location.getXPathExpression()}, + e); + } + + if (nodes.getLength() != 1 + || !(nodes.item(0).getNodeType() == Node.ELEMENT_NODE)) { + throw new MOAApplicationException( + "2212", + new Object[] { location.getXPathExpression()}); + } + return (Element) nodes.item(0); + } + + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java new file mode 100644 index 000000000..158a3ddb5 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java @@ -0,0 +1,249 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.xmlbind.ProfileParser; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileID; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileID; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileID; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileID; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * Map ProfileID objects to their explicit represantation. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ProfileMapper { + + /** The parser to parse the profiles. */ + private static ProfileParser profileParser = new ProfileParser(); + + /** + * Map a <code>CreateTransformsInfoProfile</code> to a + * <code>CreateTransformsInfoProfileExplicit</code>. + * + * @param profile The profile object to map. + * @param config The MOA configuration to use for looking up the profile. + * @return <code>profile</code>, if the given profile is of type + * <code>EXPLICIT_CREATETRANSFORMSINFOPROFILE</code>, otherwise the profile + * that is looked up and parsed from the configuration. + * @throws MOAApplicationException An error occurred parsing the profile. + */ + public static CreateTransformsInfoProfileExplicit mapCreateTransformsInfoProfile( + CreateTransformsInfoProfile profile, + ConfigurationProvider config) + throws MOAApplicationException { + + switch (profile.getCreateTransformsInfoProfileType()) { + case CreateTransformsInfoProfile.EXPLICIT_CREATETRANSFORMSINFOPROFILE : + return (CreateTransformsInfoProfileExplicit) profile; + + case CreateTransformsInfoProfile.ID_CREATETRANSFORMSINFOPROFILE : + CreateTransformsInfoProfileID profileIdObj = + (CreateTransformsInfoProfileID) profile; + String profileID = profileIdObj.getCreateTransformsInfoProfileID(); + Element profileElem = config.getCreateTransformsInfoProfile(profileID); + + if (profileElem == null) { + throw new MOAApplicationException("2234", new Object[] { profileID }); + } + + return ( + CreateTransformsInfoProfileExplicit) profileParser + .parseCreateTransformsInfoProfile( + profileElem); + } + return null; // this will not happen + } + + /** + * Map a <code>CreateSignatureEnvironmentProfile</code> to a + * <code>CreateSignatureEnvironmentProfileExplicit</code>. + * + * @param profile The profile object to map. + * @param config The MOA configuration to use for looking up the profile. + * @return <code>profile</code>, if the given profile is of type + * <code>EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE</code>, otherwise the + * profile that is looked up and parsed from the configuration. + * @throws MOAApplicationException An error occurred parsing the profile. + */ + public static CreateSignatureEnvironmentProfileExplicit mapCreateSignatureEnvironmentProfile( + CreateSignatureEnvironmentProfile profile, + ConfigurationProvider config) + throws MOAApplicationException { + + switch (profile.getCreateSignatureEnvironmentProfileType()) { + case CreateSignatureEnvironmentProfile + .EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE : + + return (CreateSignatureEnvironmentProfileExplicit) profile; + + case CreateSignatureEnvironmentProfile + .ID_CREATESIGNATUREENVIRONMENTPROFILE : + + CreateSignatureEnvironmentProfileID profileIdObj = + (CreateSignatureEnvironmentProfileID) profile; + String profileID = + profileIdObj.getCreateSignatureEnvironmentProfileID(); + Element profileElem = + config.getCreateSignatureEnvironmentProfile(profileID); + + if (profileElem == null) { + throw new MOAApplicationException("2236", new Object[] { profileID }); + } + + return ( + CreateSignatureEnvironmentProfileExplicit) profileParser + .parseCreateSignatureEnvironmentProfile( + profileElem); + + } + return null; + + } + + /** + * Map a <code>List</code> of <code>SupplementProfile</code>s to their + * explicit representation. + * + * @param profiles The profiles to map. + * @param config The MOA configuration to use for looking up profiles. + * @return The mapped profiles. + * @throws MOAApplicationException An error occurred mapping one of the + * profiles. + */ + public static List mapSupplementProfiles( + List profiles, + ConfigurationProvider config) + throws MOAApplicationException { + + List mappedProfiles = new ArrayList(); + Iterator iter; + + for (iter = profiles.iterator(); iter.hasNext();) { + SupplementProfile profile = (SupplementProfile) iter.next(); + mappedProfiles.add(mapSupplementProfile(profile, config)); + } + + return mappedProfiles; + } + + /** + * Map a <code>SupplementProfile</code> to a + * <code>SupplementProfileExplicit</code>. + * + * @param profile The profile object to map. + * @param config The MOA configuration to use for looking up the profile. + * @return <code>profile</code>, if the given profile is of type + * <code>EXPLICIT_SUPPLEMENTPROFILE</code>, otherwise the + * profile that is looked up and parsed from the configuration. + * @throws MOAApplicationException An error occurred parsing the profile. + */ + public static SupplementProfileExplicit mapSupplementProfile( + SupplementProfile profile, + ConfigurationProvider config) + throws MOAApplicationException { + + switch (profile.getSupplementProfileType()) { + case SupplementProfile.EXPLICIT_SUPPLEMENTPROFILE : + return (SupplementProfileExplicit) profile; + + case SupplementProfile.ID_SUPPLEMENTPROFILE : + SupplementProfileID profileIdObj = (SupplementProfileID) profile; + String profileID = profileIdObj.getSupplementProfileID(); + Element profileElem = config.getSupplementProfile(profileID); + + if (profileElem == null) { + throw new MOAApplicationException("2267", new Object[] { profileID }); + } + + return ( + SupplementProfileExplicit) profileParser.parseSupplementProfile( + profileElem); + } + + return null; + } + + /** + * Map a <code>List</code> of <code>VerifyTransformsInfoProfile</code>s to + * their explicit representation. + * + * @param profiles The profiles to map. + * @param config The MOA configuration to use for looking up profiles. + * @return The mapped profiles. + * @throws MOAApplicationException An error occurred mapping one of the + * profiles. + */ + public static List mapVerifyTransformsInfoProfiles( + List profiles, + ConfigurationProvider config) + throws MOAApplicationException { + + List mappedProfiles = new ArrayList(); + Iterator iter; + + for (iter = profiles.iterator(); iter.hasNext();) { + VerifyTransformsInfoProfile profile = + (VerifyTransformsInfoProfile) iter.next(); + mappedProfiles.add(mapVerifyTransformsInfoProfile(profile, config)); + } + + return mappedProfiles; + } + + /** + * Map a <code>VerifyTransformsInfoProfile</code> to a + * <code>VerifyTransformsInfoProfileExplicit</code>. + * + * @param profile The profile object to map. + * @param config The MOA configuration to use for looking up the profile. + * @return <code>profile</code>, if the given profile is of type + * <code>EXPLICIT_VERIFYTRANSFORMSINFOPROFILE</code>, otherwise the + * profile that is looked up and parsed from the configuration. + * @throws MOAApplicationException An error occurred parsing the profile. + */ + public static VerifyTransformsInfoProfileExplicit mapVerifyTransformsInfoProfile( + VerifyTransformsInfoProfile profile, + ConfigurationProvider config) + throws MOAApplicationException { + + switch (profile.getVerifyTransformsInfoProfileType()) { + case VerifyTransformsInfoProfile.EXPLICIT_VERIFYTRANSFORMSINFOPROFILE : + return (VerifyTransformsInfoProfileExplicit) profile; + + case VerifyTransformsInfoProfile.ID_VERIFYTRANSFORMSINFOPROFILE : + VerifyTransformsInfoProfileID profileIdObj = + (VerifyTransformsInfoProfileID) profile; + String profileID = profileIdObj.getVerifyTransformsInfoProfileID(); + Element profileElem = + config.getVerifyTransformsInfoProfile(profileID); + + if (profileElem == null) { + throw new MOAApplicationException("2268", new Object[] { profileID }); + } + + return ( + VerifyTransformsInfoProfileExplicit) profileParser + .parseVerifyTransformsInfoProfile( + profileElem); + } + + return null; + } +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java new file mode 100644 index 000000000..11f05a2f1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java @@ -0,0 +1,51 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import at.gv.egovernment.moa.logging.LoggingContext; +import at.gv.egovernment.moa.logging.LoggingContextManager; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; + +/** + * A utility class for setting up and tearing down thread-local context + * information needed for calling the <code>Invoker</code> classes. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ServiceContextUtils { + + /** + * Set up the thread-local context information needed for calling the various + * <code>Invoker</code> classes. + * + * @throws ConfigurationException An error occurred setting up the + * configuration in the <code>TransactionContext</code>. + */ + public static void setUpContexts() throws ConfigurationException { + TransactionContextManager txMgr = TransactionContextManager.getInstance(); + LoggingContextManager logMgr = LoggingContextManager.getInstance(); + String transactionID = Thread.currentThread().getName(); + + if (txMgr.getTransactionContext() == null) { + TransactionContext ctx = new TransactionContext(transactionID, null, ConfigurationProvider.getInstance()); + txMgr.setTransactionContext(ctx); + } + + if (logMgr.getLoggingContext() == null) { + LoggingContext ctx = new LoggingContext(transactionID); + logMgr.setLoggingContext(ctx); + } + } + + /** + * Tear down thread-local context information. + */ + public static void tearDownContexts() { + TransactionContextManager.getInstance().setTransactionContext(null); + LoggingContextManager.getInstance().setLoggingContext(null); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java new file mode 100644 index 000000000..dc5ceb21e --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java @@ -0,0 +1,45 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.util.Collections; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.Configurator; +import at.gv.egovernment.moa.spss.api.SignatureCreationService; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; + +/** + * An implementation of the <code>SignatureCreationService</code>, using + * the <code>XMLSignatureCreationInvoker</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SignatureCreationServiceImpl extends SignatureCreationService { + + /** + * Create an XML signature. + * + * @param request The <code>CreateXMLSignatureRequest</code> containing + * information about the signature(s) to create. + * @return The created signature(s). + * @throws MOAException An error occurred creating the signature(s). + */ + public CreateXMLSignatureResponse createXMLSignature(CreateXMLSignatureRequest request) + throws MOAException { + + XMLSignatureCreationInvoker invoker = + XMLSignatureCreationInvoker.getInstance(); + CreateXMLSignatureResponse response; + + try { + Configurator.getInstance().init(); + ServiceContextUtils.setUpContexts(); + response = invoker.createXMLSignature(request, Collections.EMPTY_SET); + return response; + } finally { + ServiceContextUtils.tearDownContexts(); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java new file mode 100644 index 000000000..94cdea5d9 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java @@ -0,0 +1,72 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.Configurator; +import at.gv.egovernment.moa.spss.api.SignatureVerificationService; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; + +/** + * An implementation of the <code>SignatureVerificationService</code> using + * the <code>XMLSignatureVerificationInvoker</code> and the + * <code>CMSSignatureVerificationInvoker</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SignatureVerificationServiceImpl + extends SignatureVerificationService { + + /** + * Verify a CMS signature. + * + * @param request The <code>VerifyCMSSignatureRequest</code> containing + * information about the signature verification. + * @return The result of the signature verification. + * @throws MOAException An error occurred during signature verification. + */ + public VerifyCMSSignatureResponse verifyCMSSignature(VerifyCMSSignatureRequest request) + throws MOAException { + + CMSSignatureVerificationInvoker invoker = + CMSSignatureVerificationInvoker.getInstance(); + VerifyCMSSignatureResponse response; + + try { + Configurator.getInstance().init(); + ServiceContextUtils.setUpContexts(); + response = invoker.verifyCMSSignature(request); + return response; + } finally { + ServiceContextUtils.tearDownContexts(); + } + } + + /** + * Verify an XML signature. + * + * @param request The <code>VerifyXMLSignatureRequest</code> containinig + * information about the signature verification. + * @return The result of the signature verification. + * @throws MOAException An error occurred during signature verification. + */ + public VerifyXMLSignatureResponse verifyXMLSignature(VerifyXMLSignatureRequest request) + throws MOAException { + + XMLSignatureVerificationInvoker invoker = + XMLSignatureVerificationInvoker.getInstance(); + VerifyXMLSignatureResponse response; + + try { + Configurator.getInstance().init(); + ServiceContextUtils.setUpContexts(); + response = invoker.verifyXMLSignature(request); + return response; + } finally { + ServiceContextUtils.tearDownContexts(); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java new file mode 100644 index 000000000..9984a95a5 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java @@ -0,0 +1,258 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import iaik.server.modules.xml.Base64Transformation; +import iaik.server.modules.xml.Canonicalization; +import iaik.server.modules.xml.EnvelopedSignatureTransformation; +import iaik.server.modules.xml.Transformation; +import iaik.server.modules.xml.XPath2Transformation; +import iaik.server.modules.xml.XPathTransformation; +import iaik.server.modules.xml.XSLTTransformation; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.common.ExclusiveCanonicalizationTransform; +import at.gv.egovernment.moa.spss.api.common.Transform; +import at.gv.egovernment.moa.spss.api.common.XPathFilter; +import at.gv.egovernment.moa.spss.api.common.XPathFilter2Transform; +import at.gv.egovernment.moa.spss.api.common.XPathTransform; +import at.gv.egovernment.moa.spss.api.common.XSLTTransform; +import at.gv.egovernment.moa.spss.server.iaik.xml.Base64TransformationImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.CanonicalizationImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.EnvelopedSignatureTransformationImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.ExclusiveCanonicalizationImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.XPath2FilterImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.XPath2TransformationImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.XPathTransformationImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.XSLTTransformationImpl; + +/** + * A factory to create <code>Transformation</code> objects from + * <code>Transform</code> objects. + * + * @author Patrick Peck + * @version $Id$ + */ +public class TransformationFactory { + + + /** The single instance of this class. */ + private static TransformationFactory instance = null; + + /** Maps <code>XPathFilter</code> filter types to + * <code>XPath2Transformation</code> filter types. */ + private static Map FILTER_TYPE_MAPPING; + + static { + FILTER_TYPE_MAPPING = new HashMap(); + + FILTER_TYPE_MAPPING.put( + XPathFilter.INTERSECT_TYPE, + XPath2Transformation.XPath2Filter.INTERSECTION); + FILTER_TYPE_MAPPING.put( + XPathFilter.SUBTRACT_TYPE, + XPath2Transformation.XPath2Filter.SUBTRACTION); + FILTER_TYPE_MAPPING.put( + XPathFilter.UNION_TYPE, + XPath2Transformation.XPath2Filter.UNION); + } + + /** + * Get the single instance of the factory. + * + * @return TransformationFactory The single instance. + */ + public static synchronized TransformationFactory getInstance() { + if (instance == null) { + instance = new TransformationFactory(); + } + return instance; + } + + /** + * Create a new <code>TransformationFactory</code>. + * + * Protected to disallow multiple instances. + */ + protected TransformationFactory() { + } + + /** + * Create a <code>Transformation</code> based on a + * <code>Transform</code> object. + * + * @param transform The <code>Transform</code> object to extract + * transformation data from. + * @return The transformation contained in the <code>transform</code> + * object. + * @throws MOAApplicationException An error occured creating the + * <code>Transformation</code>. See exception message for details. + */ + public Transformation createTransformation(Transform transform) + throws MOAApplicationException { + String algorithmUri = transform.getAlgorithmURI(); + + if (Canonicalization.CANONICAL_XML.equals(algorithmUri) + || Canonicalization.CANONICAL_XML_WITH_COMMENTS.equals(algorithmUri)) { + return createC14nTransformation(algorithmUri); + } else if ( + Canonicalization.EXCLUSIVE_CANONICAL_XML.equals(algorithmUri) + || Canonicalization.EXCLUSIVE_CANONICAL_XML_WITH_COMMENTS.equals( + algorithmUri)) { + + return createExclusiveC14nTransformation( + (ExclusiveCanonicalizationTransform) transform); + + } else if (Base64Transformation.ALL.contains(algorithmUri)) { + return createBase64Transformation(); + } else if (EnvelopedSignatureTransformation.ALL.contains(algorithmUri)) { + return createEnvelopedSignatureTransformation(); + } else if (XPathTransformation.ALL.contains(algorithmUri)) { + return createXPathTransformation((XPathTransform) transform); + } else if (XPath2Transformation.ALL.contains(algorithmUri)) { + return createXPath2Transformation((XPathFilter2Transform) transform); + } else if (XSLTTransformation.ALL.contains(algorithmUri)) { + return createXSLTTransformation((XSLTTransform) transform); + } else { + throw new MOAApplicationException("1108", new Object[] { algorithmUri }); + } + } + + /** + * Create a <code>List</code> of <code>Transformation</code>s from a + * <code>List</code> of <code>Transform</code>s. + * + * @param transforms The <code>List</code> containing the + * <code>Transform</code>s. + * @return The <code>List</code> of <code>Transformation</code>s corresponding + * to the <code>transforms</code>. + * @throws MOAApplicationException An error occurred building one of the + * transformations. See exception message for details. + */ + public List createTransformationList(List transforms) + throws MOAApplicationException { + List transformationList = new ArrayList(); + Iterator trIter; + + for (trIter = transforms.iterator(); trIter.hasNext();) { + Transform transform = (Transform) trIter.next(); + transformationList.add(createTransformation(transform)); + } + + return transformationList; + } + + /** + * Create a <code>Canonicalization</code>. + * + * @param algorithmUri The algorithm URI of the canonicalization. + * @return The <code>Canonicalization</code>. + */ + private Transformation createC14nTransformation(String algorithmUri) { + return new CanonicalizationImpl(algorithmUri); + } + + /** + * Create a <code>ExclusiveCanonicalization</code>. + * + * @param transform The <code>ExclusiveCanonicalizationTransform</code> + * containing the transformation data. + * @return The <code>ExclusiveCanonicalization</code>. + */ + private Transformation createExclusiveC14nTransformation(ExclusiveCanonicalizationTransform transform) { + return new ExclusiveCanonicalizationImpl( + transform.getAlgorithmURI(), + transform.getInclusiveNamespacePrefixes()); + } + + /** + * Create a <code>Base64Transformation</code>. + * + * @return The <code></code> + */ + private Transformation createBase64Transformation() { + return new Base64TransformationImpl(); + } + + /** + * Create an <code>EnvelopedSignatureTransformation</code>. + * + * @return An <code>EnvelopedSignatureTransformation</code>. + */ + private Transformation createEnvelopedSignatureTransformation() { + return new EnvelopedSignatureTransformationImpl(); + } + + /** + * Create an <code>XPathTransformation</code>. + * + * @param transform The <code>Transform</code> object containing the + * XPath transformation. + * @return An <code>XPathTransformation</code> corresponding the + * transformation given in <code>transform</code>. + * @throws MOAApplicationException An error occurred creating the + * <code>Transformation</code>. + */ + private Transformation createXPathTransformation(XPathTransform transform) + throws MOAApplicationException { + + return new XPathTransformationImpl( + transform.getXPathExpression(), + transform.getNamespaceDeclarations()); + } + + /** + * Create an <code>XPath2Transformation</code>. + * + * @param transform The <code>Transform</code> object containing the + * XPath filter transformation. + * @return An <code>XPath2Transformation</code> corresponding the + * transformation given in <code>transform</code>. + * @throws MOAApplicationException An error occurred creating the + * <code>Transformation</code>. + */ + private Transformation createXPath2Transformation(XPathFilter2Transform transform) + throws MOAApplicationException { + + XPath2TransformationImpl xpath2 = new XPath2TransformationImpl(); + Iterator iter; + + for (iter = transform.getFilters().iterator(); iter.hasNext();) { + XPathFilter filter = (XPathFilter) iter.next(); + String mappedFilterType = + (String) FILTER_TYPE_MAPPING.get(filter.getFilterType()); + XPath2FilterImpl mappedFilter = + new XPath2FilterImpl( + mappedFilterType, + filter.getXPathExpression(), + filter.getNamespaceDeclarations()); + xpath2.addXPathFilter(mappedFilter); + } + + if (xpath2.getXPathFilters().size() == 0) { + throw new MOAApplicationException("2216", null); + } + + return xpath2; + } + + /** + * Create an <code>XSLTTransformation</code>. + * + * @param transform The <code>Transform</code> containing the XSLT stylesheet. + * @return An <code>XSLTTransformation</code> corresponding the transformation + * given in <code>transform</code>. + * @throws MOAApplicationException An error occurred creating the + * <code>Transformation</code>. + */ + private Transformation createXSLTTransformation(XSLTTransform transform) + throws MOAApplicationException { + + return new XSLTTransformationImpl(transform.getStylesheet()); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java new file mode 100644 index 000000000..55e2e1505 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java @@ -0,0 +1,86 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import iaik.server.modules.cmsverify.CMSSignatureVerificationResult; +import iaik.server.modules.cmsverify.CertificateValidationResult; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; + +/** + * A class to build a <code>VerifyCMSSignatureResponse</code> object. + * + * <p>Via subsequent calls to <code>addResult()</code> a number of results from + * a CMS signature verification can be added to the response.</p> + * + * <p>The <code>getResponseElement()</code> method then returns the + * <code>VerifyCMSSignatureResponse</code> built so far.</p> + * + * @author Patrick Peck + * @version $Id$ + */ +public class VerifyCMSSignatureResponseBuilder { + /** The <code>SPSSFactory</code> for creating API objects. */ + private SPSSFactory factory = SPSSFactory.getInstance(); + /** The elements making up the response. */ + private List responseElements = new ArrayList(); + + /** + * Get the <code>VerifyCMSSignatureResponse</code> built so far. + * + * @return The <code>VerifyCMSSignatureResponse</code> built so far. + */ + public VerifyCMSSignatureResponse getResponse() { + return factory.createVerifyCMSSignatureResponse(responseElements); + } + + /** + * Add a verification result to the response. + * + * @param result The result to add. + * @throws MOAApplicationException An error occurred adding the result. + */ + public void addResult(CMSSignatureVerificationResult result) + throws MOAApplicationException { + + CertificateValidationResult certResult = + result.getCertificateValidationResult(); + int signatureCheckCode = + result.getSignatureValueVerificationCode().intValue(); + int certificateCheckCode = certResult.getValidationResultCode().intValue(); + VerifyCMSSignatureResponseElement responseElement; + SignerInfo signerInfo; + CheckResult signatureCheck; + CheckResult certificateCheck; + + // add SignerInfo element + signerInfo = + factory.createSignerInfo( + (X509Certificate) certResult.getCertificateChain().get(0), + certResult.isQualifiedCertificate(), + certResult.isPublicAuthorityCertificate(), + certResult.getPublicAuthorityID()); + + // add SignatureCheck element + signatureCheck = factory.createCheckResult(signatureCheckCode, null); + + // add CertificateCheck element + certificateCheck = factory.createCheckResult(certificateCheckCode, null); + + // build the response element + responseElement = + factory.createVerifyCMSSignatureResponseElement( + signerInfo, + signatureCheck, + certificateCheck); + responseElements.add(responseElement); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java new file mode 100644 index 000000000..2f55261d1 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java @@ -0,0 +1,317 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.NodeList; + +import iaik.ixsil.algorithms.CanonicalizationAlgorithm; +import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplExclusiveCanonicalXMLWithComments; +import iaik.server.modules.xml.BinaryDataObject; +import iaik.server.modules.xml.DataObject; +import iaik.server.modules.xml.XMLDataObject; +import iaik.server.modules.xml.XMLNodeListDataObject; +import iaik.server.modules.xmlverify.CertificateValidationResult; +import iaik.server.modules.xmlverify.DsigManifest; +import iaik.server.modules.xmlverify.HashUnavailableException; +import iaik.server.modules.xmlverify.ReferenceData; +import iaik.server.modules.xmlverify.ReferenceInfo; +import iaik.server.modules.xmlverify.SecurityLayerManifest; +import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile; +import iaik.server.modules.xmlverify.XMLSignatureVerificationResult; +import iaik.x509.X509Certificate; + +import at.gv.egovernment.moa.util.CollectionUtils; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.NodeListAdapter; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResultInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; + +/** + * A class to build a <code>VerifyXMLSignatureResponse</code> object. + * + * <p>Via a call to <code>addResult()</code> the only result of the + * signature verification must be added.</p> + * + * <p>The <code>getResponseElement()</code> method then returns the + * <code>VerifyXMLSignatureResponse</code> built so far.</p> + * + * @author Patrick Peck + * @version $Id$ + */ +public class VerifyXMLSignatureResponseBuilder { + /** The <code>SPSSFactory</code> for creating API objects. */ + private SPSSFactory factory = SPSSFactory.getInstance(); + + /** Information about the signer certificate. */ + private SignerInfo signerInfo; + /** The hash input data. */ + private List hashInputDatas; + /** The reference input data. */ + private List referenceInputDatas; + /** The result of the signature check. */ + private ReferencesCheckResult signatureCheck; + /** The result of the signature manifest check. */ + private ReferencesCheckResult signatureManifestCheck; + /** The result of the XMLDsig manifest check. */ + private List xmlDsigManifestChecks; + /** The result of the certificate check. */ + private CheckResult certificateCheck; + + /** + * Get the <code>VerifyMLSignatureResponse</code> built so far. + * + * @return The <code>VerifyXMLSignatureResponse</code> built so far. + */ + public VerifyXMLSignatureResponse getResponse() { + return factory.createVerifyXMLSignatureResponse( + signerInfo, + hashInputDatas, + referenceInputDatas, + signatureCheck, + signatureManifestCheck, + xmlDsigManifestChecks, + certificateCheck); + } + + /** + * Sets the verification result to the response. + * + * This method must be called exactly once to ensure a valid + * <code>VerifyXMLSignatureResponse</code>. + * + * @param result The result to set for the response. + * @param profile The profile used for verifying the signature. + * @throws MOAApplicationException An error occurred adding the result. + */ + public void setResult( + XMLSignatureVerificationResult result, + XMLSignatureVerificationProfile profile, + ReferencesCheckResult transformsSignatureManifestCheck) + throws MOAApplicationException { + + CertificateValidationResult certResult = + result.getCertificateValidationResult(); + List referenceDataList; + ReferenceData referenceData; + List dsigManifestList; + ReferencesCheckResultInfo checkResultInfo; + int[] failedReferences; + Iterator iter; + + // create the SignerInfo; + signerInfo = + factory.createSignerInfo( + (X509Certificate) certResult.getCertificateChain().get(0), + certResult.isQualifiedCertificate(), + certResult.isPublicAuthorityCertificate(), + certResult.getPublicAuthorityID()); + + // add HashInputData Content objects + referenceDataList = result.getReferenceDataList(); + if (profile.includeHashInputData()) { + hashInputDatas = new ArrayList(); + for (iter = referenceDataList.iterator(); iter.hasNext();) { + referenceData = (ReferenceData) iter.next(); + hashInputDatas.add(buildContent(referenceData.getHashInputData())); + } + } + + // create the ReferenceInputData Content objects + if (profile.includeReferenceInputData()) { + referenceInputDatas = new ArrayList(); + for (iter = referenceDataList.iterator(); iter.hasNext();) { + referenceData = (ReferenceData) iter.next(); + referenceInputDatas.add( + buildContent(referenceData.getReferenceInputData())); + } + } + + // create the signature check + failedReferences = buildFailedReferences(result.getReferenceDataList()); + checkResultInfo = + failedReferences != null + ? factory.createReferencesCheckResultInfo(null, failedReferences) + : null; + signatureCheck = + factory.createReferencesCheckResult( + result.getSignatureValueVerificationCode().intValue(), + checkResultInfo); + + // create the signature manifest check + if (profile.checkSecurityLayerManifest()) { + if (transformsSignatureManifestCheck.getCode() == 1) { + // checking the transforms failed + signatureManifestCheck = transformsSignatureManifestCheck; + } else if (!result.containsSecurityLayerManifest()) { + // no security layer manifest in signature + signatureManifestCheck = factory.createReferencesCheckResult(2, null); + } else { + // other error codes provided by IAIK signature verification + // need to add 1 to the check code for MOA compatibility + SecurityLayerManifest slManifest = result.getSecurityLayerManifest(); + int verificationResult = + slManifest.getManifestVerificationResult().intValue(); + + switch (verificationResult) { + case 0 : + signatureManifestCheck = + factory.createReferencesCheckResult(0, null); + break; + case 2 : + case 3 : + failedReferences = + buildFailedReferences(slManifest.getReferenceInfoList()); + checkResultInfo = + failedReferences != null + ? factory.createReferencesCheckResultInfo(null, failedReferences) + : null; + signatureManifestCheck = + factory.createReferencesCheckResult( + verificationResult + 1, + checkResultInfo); + } + } + + // Code = 1 prüfen + + if (result.containsSecurityLayerManifest()) { + } else { + // SignatureManifestCheck Code = 2 + } + } + + // create the xmlDsigManifestCheck + if (profile.checkXMLDsigManifests()) { + xmlDsigManifestChecks = new ArrayList(); + dsigManifestList = result.getDsigManifestList(); + for (iter = dsigManifestList.iterator(); iter.hasNext();) { + DsigManifest dsigManifest = (DsigManifest) iter.next(); + int refIndex = + dsigManifest.getReferringReferenceInfo().getReferenceIndex(); + ManifestRefsCheckResultInfo manifestCheckResultInfo; + + failedReferences = + buildFailedReferences(dsigManifest.getReferenceInfoList()); + manifestCheckResultInfo = + factory.createManifestRefsCheckResultInfo( + null, + failedReferences, + refIndex); + xmlDsigManifestChecks.add( + factory.createManifestRefsCheckResult( + dsigManifest.getManifestVerificationResult().intValue(), + manifestCheckResultInfo)); + } + } + + // create the certificate check + certificateCheck = + factory.createCheckResult( + certResult.getValidationResultCode().intValue(), + null); + } + + /** + * Build a <code>Content</code> object from the given <code>DataObject</code>. + * + * @param dataObject The <code>DataObject</code> from which to build the + * <code>Content</code>. Based on the type of this parameter, the type of + * <code>Content</code> will either be <code>XML_CONTENT</code> or + * <code>BINARY_CONTENT</code>. + * @return The <code>Content</code> object containing the data. + * @throws MOAApplicationException An error occurred adding the content. + */ + private Content buildContent(DataObject dataObject) + throws MOAApplicationException { + + if (dataObject instanceof BinaryDataObject) { + BinaryDataObject binaryData = (BinaryDataObject) dataObject; + return factory.createContent(binaryData.getInputStream(), null); + } else if (dataObject instanceof XMLDataObject) { + XMLDataObject xmlData = (XMLDataObject) dataObject; + List nodes = new ArrayList(); + + nodes.add(xmlData.getElement()); + return factory.createContent(new NodeListAdapter(nodes), null); + } else { // dataObject instanceof XMLNodeListDataObject + // if the data in the NodeList can be converted back to valid XML, + // write it as XMLContent; otherwise, write it as Base64Content + XMLNodeListDataObject nodeData = (XMLNodeListDataObject) dataObject; + NodeList nodes = nodeData.getNodeList(); + + if (DOMUtils.checkAttributeParentsInNodeList(nodes)) { + // insert as XMLContent + try { + DocumentFragment fragment = DOMUtils.nodeList2DocumentFragment(nodes); + + return factory.createContent(fragment.getChildNodes(), null); + } catch (Exception e) { + // not successful -> fall through to the Base64Content + } + } + + // insert canonicalized NodeList as binary content + try { + CanonicalizationAlgorithm c14n = + new CanonicalizationAlgorithmImplExclusiveCanonicalXMLWithComments(); + InputStream is; + + c14n.setInput(nodes); + is = c14n.canonicalize(); + return factory.createContent(is, null); + } catch (Exception e) { + throw new MOAApplicationException("2200", null); + } + } + } + + /** + * Build the failed references. + * + * Failed references are references for which the <code>isHashValid()</code> + * method returns <code>false</code>. + * + * @param refInfos A <code>List</code> containing the + * <code>ReferenceInfo</code> objects to be checked. + * @return The indexes of the failed references. + */ + private int[] buildFailedReferences(List refInfos) { + List failedReferencesList = new ArrayList(); + int i; + + // find out the failed references + for (i = 0; i < refInfos.size(); i++) { + ReferenceInfo refInfo = (ReferenceInfo) refInfos.get(i); + + try { + if (refInfo.isHashCalculated() && !refInfo.isHashValid()) { + failedReferencesList.add(new Integer(i + 1)); + } + } catch (HashUnavailableException e) { + // nothing to do here because we called refInfo.isHashCalculated first + } + } + + // convert to an int array + if (failedReferencesList.isEmpty()) { + return null; + } else { + int[] failedReferences = CollectionUtils.toIntArray(failedReferencesList); + + return failedReferences; + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java new file mode 100644 index 000000000..6b8a3db2d --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java @@ -0,0 +1,522 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import iaik.IAIKException; +import iaik.IAIKRuntimeException; +import iaik.server.modules.xml.DataObject; +import iaik.server.modules.xml.XMLDataObject; +import iaik.server.modules.xml.XMLSignature; +import iaik.server.modules.xmlsign.XMLSignatureCreationModule; +import iaik.server.modules.xmlsign.XMLSignatureCreationModuleFactory; +import iaik.server.modules.xmlsign.XMLSignatureCreationProfile; + +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.logging.LoggingContext; +import at.gv.egovernment.moa.logging.LoggingContextManager; +import at.gv.egovernment.moa.util.DateTimeUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.xml.SigningTimeImpl; +import at.gv.egovernment.moa.spss.server.iaik.xml.XMLDataObjectImpl; +import at.gv.egovernment.moa.spss.server.logging.IaikLog; +import at.gv.egovernment.moa.spss.server.logging.TransactionId; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; +import at.gv.egovernment.moa.spss.server.util.IdGenerator; + +/** + * A class providing an API based interface to the + * <code>XMLSignatureCreationModule</code>. + * + * This class performs the invocation of the + * <code>iaik.server.modules.xmlsign.XMLSignatureCreationModule</code> from a + * <code>CreateXMLSignatureRequest</code> given as an API object. The result of + * the invocation is integrated into a <code>CreateXMLSignatureResponse</code> + * and returned. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureCreationInvoker { + + /** The single instance of this class. */ + private static XMLSignatureCreationInvoker instance = null; + + /** + * Get the only instance of this class. + * + * @return The only instance of this class. + */ + public static synchronized XMLSignatureCreationInvoker getInstance() { + if (instance == null) { + instance = new XMLSignatureCreationInvoker(); + } + return instance; + } + + /** + * Create a new <code>XMLSignatureCreationInvoker</code>. + * + * Protected to disallow multiple instances. + */ + protected XMLSignatureCreationInvoker() { + } + + /** + * Process the <code>CreateXMLSignatureRequest<code> message and invoke the + * <code>XMLSignatureCreationModule</code> for every + * <code>SingleSignatureInfo</code> contained in the request. + * + * @param request A <code>CreateXMLSignatureRequest<code> API object + * containing the information for creating the signature(s). + * @param reserved A <code>Set</code> of reserved object IDs. + * + * @return A <code>CreateXMLSignatureResponse</code> API object containing + * the created signature(s). The response contains either a + * <code>SignatureEnvironment</code> or a <code>ErrorResponse</code> + * for each <code>SingleSignatureInfo</code> in the request. + * @throws MOAException An error occurred during signature creation. + */ + public CreateXMLSignatureResponse createXMLSignature( + CreateXMLSignatureRequest request, + Set reserved) + throws MOAException { + + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + LoggingContext loggingCtx = + LoggingContextManager.getInstance().getLoggingContext(); + Set reservedIDs = new HashSet(reserved); + XMLSignatureCreationProfileFactory profileFactory = + new XMLSignatureCreationProfileFactory(request, reservedIDs); + CreateXMLSignatureResponseBuilder responseBuilder = + new CreateXMLSignatureResponseBuilder(); + int createCount = 1; + IdGenerator refIdGen; + XMLSignatureCreationModule module; + Iterator singleSignatureInfoIter; + + // create the XMLSignatureCreationModule and configure it + module = XMLSignatureCreationModuleFactory.getInstance(); + module.setLog(new IaikLog(loggingCtx.getNodeID())); + + // select the SingleSignatureInfo elements + singleSignatureInfoIter = request.getSingleSignatureInfos().iterator(); + + // iterate over all the SingleSignatureInfo elements in the request + while (singleSignatureInfoIter.hasNext()) { + SingleSignatureInfo singleSignatureInfo = + (SingleSignatureInfo) singleSignatureInfoIter.next(); + CreateSignatureInfo createSignatureInfo; + List dataObjectList; + XMLSignatureCreationProfile profile; + XMLDataObject signatureEnvironment; + XMLDataObject signatureParent; + XMLSignature signature; + List additionalSignedProperties; + Node signatureEnvironmentParent = null; + Element requestElement = null; + + try { + // create the reference id generator + refIdGen = new IdGenerator("reference-" + createCount++, reservedIDs); + + // build the signature environment + createSignatureInfo = singleSignatureInfo.getCreateSignatureInfo(); + if (createSignatureInfo != null) { + DataObjectFactory dataObjFactory = DataObjectFactory.getInstance(); + + signatureEnvironment = + dataObjFactory.createSignatureEnvironment( + createSignatureInfo.getCreateSignatureEnvironment(), + getCreateSignatureEnvironmentProfileSupplements(singleSignatureInfo)); + } else { + signatureEnvironment = null; + } + + // build the list of DataObjects + dataObjectList = + buildDataObjectList( + singleSignatureInfo, + signatureEnvironment, + refIdGen); + + // build the XMLSignatureCreationProfile + profile = profileFactory.createProfile(singleSignatureInfo); + + // build the additionalSignedProperties + additionalSignedProperties = buildAdditionalSignedProperties(); + + // build the signatureParentElement + if (signatureEnvironment != null) { + signatureParent = + buildSignatureParentElement( + signatureEnvironment.getElement(), + singleSignatureInfo); + } else { + signatureParent = null; + } + + // make the signature environment the root of the document, if it is + // not a separate document anyway; this is done to assure that + // canonicalization of the signature environment contains the correct + // namespace declarations + if (signatureEnvironment != null) { + Document requestDoc = + signatureEnvironment.getElement().getOwnerDocument(); + requestElement = requestDoc.getDocumentElement(); + if (requestElement != signatureEnvironment.getElement()) { + signatureEnvironmentParent = + signatureEnvironment.getElement().getParentNode(); + requestElement.getOwnerDocument().replaceChild( + signatureEnvironment.getElement(), + requestElement); + } + } + + try { + // create the signature + signature = + module.createSignature( + dataObjectList, + profile, + additionalSignedProperties, + signatureParent, + new TransactionId(context.getTransactionID())); + + // insert the result into the response + if (signatureParent != null) { + responseBuilder.addSignatureEnvironment( + signatureParent.getElement()); + } else { + responseBuilder.addSignatureEnvironment(signature.getElement()); + } + + } catch (IAIKException e) { + MOAException moaException = IaikExceptionMapper.getInstance().map(e); + + responseBuilder.addError( + moaException.getMessageId(), + moaException.getMessage()); + Logger.warn(moaException.getMessage(), e); + } catch (IAIKRuntimeException e) { + MOAException moaException = IaikExceptionMapper.getInstance().map(e); + + responseBuilder.addError( + moaException.getMessageId(), + moaException.getMessage()); + Logger.warn(moaException.getMessage(), e); + } + + // swap back in the request as root document + if (signatureEnvironment != null) { + if (requestElement != signatureEnvironment.getElement()) { + requestElement.getOwnerDocument().replaceChild( + requestElement, + signatureEnvironment.getElement()); + signatureEnvironmentParent.appendChild( + signatureEnvironment.getElement()); + } + } + + } catch (MOAException e) { + responseBuilder.addError(e.getMessageId(), e.getMessage()); + Logger.warn(e.getMessage(), e); + } + + } + + return responseBuilder.getResponse(); + } + + /** + * Build the list of <code>DataObject</code>s from the given + * <code>SingleSignatureInfo</code> object. + * + * <p> + * Only the following cases of <code>DataObject</code>s are + * valid in case of an enveloping signature: + * + * <ul> + * <li><code>Reference == null && Content != null</code>: The + * <code>Content</code> will be used in the <code>DataObject</code>.</li> + * <li><code>Reference != null && Content == null</code>: Resolve the + * <code>Reference</code> and use it as <code>DataObject</code>. + * Set the <code>Reference</code> in the <code>DataObject</code> as well.</li> + * </ul> + * </p> + * + * <p> + * Only the following cases of <code>DataObject</code>s are valid in case + * of a detached signature: + * + * <ul> + * <li><code>Reference != null && Content == null</code>: Resolve the + * <code>Reference</code> and use it as <code>DataObject</code>. + * Set the <code>Reference</code> in the <code>DataObject</code> as well.</li> + * <li><code>Reference != null && Content != null</code>: The + * <code>Content</code> will be used in the <code>DataObject</code>. + * Set the <code>Reference</code> in the <code>DataObject</code> as well.</li> + * </ul> + * </p> + * + * <p> + * All other cases will lead to an error. + * </p> + * + * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object + * containing the <code>DataObjectInfo</code> objects. + * @param signatureEnvironment The + * @param idGen The ID generator for <code>DataObject</code> references. + * @return The <code>List</code> of <code>DataObject</code>s contained in the + * given <code>singleSignatureInfo</code>. + * @throws MOASystemException A system error occurred building the data + * objects. + * @throws MOAApplicationException An error occurred building the data + * objects. + */ + private List buildDataObjectList( + SingleSignatureInfo singleSignatureInfo, + XMLDataObject signatureEnvironment, + IdGenerator idGen) + throws MOASystemException, MOAApplicationException { + + List dataObjInfos = singleSignatureInfo.getDataObjectInfos(); + List dataObjects = new ArrayList(); + //Document requestDoc = singleSignatureInfo.getOwnerDocument(); + Iterator dtIter; + + for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) { + DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next(); + String structure = dataObjInfo.getStructure(); + + if (DataObjectInfo.STRUCTURE_ENVELOPING.equals(structure)) { + dataObjects.add( + buildEnvelopingDataObject( + dataObjInfo.getDataObject(), + idGen.nextId())); + } else if (DataObjectInfo.STRUCTURE_DETACHED.equals(structure)) { + dataObjects.add( + buildDetachedDataObject( + dataObjInfo.getDataObject(), + signatureEnvironment, + idGen.nextId())); + } else { + throw new MOAApplicationException("1103", new Object[] { structure }); + } + } + + return dataObjects; + + } + + /** + * Build a <code>DataObject</code> to be used in an enveloping + * signature. + * + * @param content The <code>Content</code> object containing the data object. + * <code>ContentOptionalRefType</code>. + * @param referenceID The reference ID to use in the signature for the + * <code>DataObject</code> created. + * @return The <code>DataObject</code> representing the data contained in + * <code>dataObjectElem</code>. + * @throws MOAApplicationException An error occurred during the creation of + * the <code>DataObject</code>. + * @throws MOASystemException A system error occurred during the creation of + * the <code>DataObject</code>. + */ + private DataObject buildEnvelopingDataObject( + Content content, + String referenceID) + throws MOASystemException, MOAApplicationException { + + DataObjectFactory factory = DataObjectFactory.getInstance(); + DataObject dataObject; + + dataObject = + factory.createFromContentOptionalRefType( + content, + referenceID, + false, + false, + true, + false); + + return dataObject; + } + + /** + * Build a <code>DataObject</code> to be used in a detached signature. + * + * @param content The <code>Content</code> object containing an the data. + * @param signatureEnvironment The signature environment where the signature + * will be inserted. + * @param referenceID The reference ID to use in the signature for the + * <code>DataObject</code> created. + * @return The <code>DataObject</code> representing the data contained in + * <code>dataObjectElem</code>. + * @throws MOAApplicationException An error occurred during the creation of + * the <code>DataObject</code>. + * @throws MOASystemException A system error occurred during the creation of + * the <code>DataObject</code>. + */ + private DataObject buildDetachedDataObject( + Content content, + XMLDataObject signatureEnvironment, + String referenceID) + throws MOASystemException, MOAApplicationException { + + String reference = content.getReference(); + DataObjectFactory factory = DataObjectFactory.getInstance(); + DataObject dataObject; + + if (reference == null) { + throw new MOAApplicationException("1102", null); + } else if ("".equals(reference) || reference.startsWith("#")) { + dataObject = + factory.createFromSignatureEnvironment( + signatureEnvironment.getElement(), + reference, + referenceID); + } else { + dataObject = + factory.createFromContentOptionalRefType( + content, + referenceID, + true, + false, + true, + false); + } + return dataObject; + } + + /** + * Build the signature parent element. + * + * @param signatureEnvironment The signature environment containing the + * document in which to insert the signature. + * @param singleSignatureInfo The <code>SingleSignatureInfo</code> + * containing the signature parent element. + * @return An <code>XMLDataObject</code> containing the signature parent + * element or <code>null</code>, if the <code>CreateSignatureInfo</code> is + * <code>null</code>. + * @throws MOAApplicationException An error occurred during the creation of + * the signature parent. + */ + private XMLDataObject buildSignatureParentElement( + Element signatureEnvironment, + SingleSignatureInfo singleSignatureInfo) + throws MOAApplicationException { + + CreateSignatureInfo createInfo = + singleSignatureInfo.getCreateSignatureInfo(); + + // evaluate the CreateSignatureLocation + if (createInfo != null) { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + CreateSignatureEnvironmentProfileExplicit createProfile = + ProfileMapper.mapCreateSignatureEnvironmentProfile( + createInfo.getCreateSignatureEnvironmentProfile(), + config); + CreateSignatureLocation location = + createProfile.getCreateSignatureLocation(); + Element signatureParent = + InvokerUtils.evaluateSignatureLocation(signatureEnvironment, location); + + return new XMLDataObjectImpl(signatureParent); + } else { + return null; + } + } + + /** + * Get the supplements contained in the + * <code>CreateSignatureEnvironmentProfile</code> of the given + * <code>SingleSignatureInfo</code>. + * + * @param singleSigInfo The <code>SingleSignatureInfo</code> from which + * to extract the supplements. + * @return A <code>List</code> of <code>XMLDataObjectAssociation</code>s + * or <code>null</code>, if the <code>singleSigInfo</code> does not contain + * supplements. + * @throws MOAApplicationException An error occurred parsing the + * <code>CreateSignatureEnvironmentProfile</code>. + */ + private List getCreateSignatureEnvironmentProfileSupplements(SingleSignatureInfo singleSigInfo) + throws MOAApplicationException { + CreateSignatureInfo sigInfo = singleSigInfo.getCreateSignatureInfo(); + + if (sigInfo != null) { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + CreateSignatureEnvironmentProfileExplicit profile = + ProfileMapper.mapCreateSignatureEnvironmentProfile( + sigInfo.getCreateSignatureEnvironmentProfile(), + config); + List supplements = profile.getSupplements(); + + return supplements; + } + return null; + } + + /** + * Build the list of additional signed properties. + * + * Based on the generic configuration setting + * <code>ConfigurationProvider.TEST_SIGNING_TIME_PROPERTY</code>, a + * constant <code>SigningTime</code> will be added to the properties. + * + * @return The <code>List</code> of additional signed properties. + */ + private List buildAdditionalSignedProperties() { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + List additionalSignedProperties = Collections.EMPTY_LIST; + String testSigningTime = + config.getGenericConfiguration( + ConfigurationProvider.TEST_SIGNING_TIME_PROPERTY); + + if (testSigningTime != null) { + try { + SigningTimeImpl signingTime = + new SigningTimeImpl(DateTimeUtils.parseDateTime(testSigningTime)); + additionalSignedProperties = new ArrayList(); + additionalSignedProperties.add(signingTime); + } catch (ParseException e) { + // if we fail here, the signing time will simply not be added to + // the list of signed properties + } + } + + return additionalSignedProperties; + } + +}
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java new file mode 100644 index 000000000..c9bb12f75 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java @@ -0,0 +1,448 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.math.BigInteger; +import java.security.Principal; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import iaik.server.modules.algorithms.HashAlgorithms; +import iaik.server.modules.keys.KeyEntryID; +import iaik.server.modules.keys.KeyModule; +import iaik.server.modules.keys.KeyModuleFactory; +import iaik.server.modules.xmlsign.SignatureStructureTypes; +import iaik.server.modules.xmlsign.XMLSignatureCreationProfile; +import iaik.server.modules.xmlsign.XMLSignatureInsertionLocation; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo; +import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.config.KeyGroupEntry; +import at.gv.egovernment.moa.spss.server.iaik.xml.CanonicalizationImpl; +import at.gv.egovernment.moa.spss.server.iaik.xmlsign.DataObjectTreatmentImpl; +import at.gv.egovernment.moa.spss.server.iaik.xmlsign.XMLSignatureCreationProfileImpl; +import at.gv.egovernment.moa.spss.server.iaik.xmlsign.XMLSignatureInsertionLocationImpl; +import at.gv.egovernment.moa.spss.server.logging.TransactionId; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; +import at.gv.egovernment.moa.spss.server.util.IdGenerator; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A factory to create <code>XMLSignatureCreationProfile</code>s from a + * <code>CreateXMLSignatureRequest</code>, based on the current MOA + * configuration. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureCreationProfileFactory { + + private static Map HASH_ALGORITHM_MAPPING; + + static { + HASH_ALGORITHM_MAPPING = new HashMap(); + HASH_ALGORITHM_MAPPING.put(Constants.SHA1_URI, HashAlgorithms.SHA1); + } + + /** The <code>CreateXMLSignatureRequest</code> for which to create the + * profile.*/ + private CreateXMLSignatureRequest request; + /** How many profiles have been created based on the same request. */ + private int createProfileCount; + /** The <code>Set</code> of reserved object IDs.*/ + private Set reserved; + + /** + * Create a new <code>XMLSignatureCreationProfileFactory</code>. + * + * @param request The request for which to create profiles. + * @param reserved The <code>Set</code> of reserved object IDs. IDs will + * be added during signature creation. + */ + public XMLSignatureCreationProfileFactory( + CreateXMLSignatureRequest request, + Set reserved) { + this.request = request; + this.reserved = reserved; + createProfileCount = 1; + } + + /** + * Create a <code>XMLSignatureCreationProfile</code> for the given + * <code>SingleSignatureInfo</code> object.. + * + * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object + * containing information about the creation of a signature. + * @return The <code>XMLSignatureCreationProfile</code> containing additional + * information for creating an XML signature. + * @throws MOASystemException A system error occurred during creation of the + * profile. See message for details + * @throws MOAApplicationException An application error occurred during + * creation of the profile. See message for details. + */ + public XMLSignatureCreationProfile createProfile(SingleSignatureInfo singleSignatureInfo) + throws MOASystemException, MOAApplicationException { + + XMLSignatureCreationProfileImpl profile = + new XMLSignatureCreationProfileImpl(createProfileCount, reserved); + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + CanonicalizationImpl canonicalization; + List dataObjectTreatmentList; + String keyGroupID; + Set keySet; + List transformationSupplements; + List createTransformsProfiles; + + // build the transformation supplements + createTransformsProfiles = + getCreateTransformsInfoProfiles(singleSignatureInfo); + transformationSupplements = + buildTransformationSupplements(createTransformsProfiles); + + // build and set the data object treatment list + dataObjectTreatmentList = + buildDataObjectTreatmentList( + singleSignatureInfo, + createTransformsProfiles, + transformationSupplements); + profile.setDataObjectTreatmentList(dataObjectTreatmentList); + + // set the key set + keyGroupID = request.getKeyIdentifier(); + keySet = buildKeySet(keyGroupID); + if (keySet == null) { + throw new MOAApplicationException("2231", null); + } else if (keySet.size() == 0) { + throw new MOAApplicationException("2232", null); + } + profile.setKeySet(keySet); + + // set the Security Layer manifest algorithm name + profile.setSecurityLayerManifestTypeURI(Constants.SL_MANIFEST_TYPE_URI); + + // set the structure type + if (singleSignatureInfo.getCreateSignatureInfo() != null) { + profile.setSignatureStructureType(SignatureStructureTypes.ENVELOPED); + } else { + profile.setSignatureStructureType(SignatureStructureTypes.DETACHED); + } + + // set insertion location + profile.setSignatureInsertionLocation( + getSignatureInsertionLocationIndex(singleSignatureInfo)); + + // set the canonicalization algorithm + canonicalization = + new CanonicalizationImpl(config.getCanonicalizationAlgorithmName()); + profile.setSignedInfoCanonicalization(canonicalization); + + // set the signed properties + profile.setSignedProperties(Collections.EMPTY_LIST); + + // set security layer conformity + profile.setSecurityLayerConform( + singleSignatureInfo.isSecurityLayerConform()); + + // update the createProfileCount + createProfileCount++; + + return profile; + } + + /** + * Get the <code>List</code> of all <code>CreateTransformsInfoProfile</code>s + * contained in all the <code>DataObjectInfo</code>s of the given + * <code>SingleSignatureInfo</code>. + * + * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object from + * which to extract the <code>CreateTransformsInfoProfile</code>s. + * @return All <code>CreateTransformsInfoProfile</code>s of all + * <code>DataObjectInfo</code>s of <code>singleSignatureInfo</code>. + * @throws MOAApplicationException An error occurred creating one of the + * profiles. + */ + private List getCreateTransformsInfoProfiles(SingleSignatureInfo singleSignatureInfo) + throws MOAApplicationException { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + List dataObjInfos = singleSignatureInfo.getDataObjectInfos(); + List profiles = new ArrayList(); + Iterator dtIter; + + for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) { + DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next(); + CreateTransformsInfoProfileExplicit profile = + ProfileMapper.mapCreateTransformsInfoProfile( + dataObjInfo.getCreateTransformsInfoProfile(), + config); + profiles.add(profile); + } + + return profiles; + } + + /** + * Build the <code>List</code> of transformation supplements contained in a + * <code>SingleSignatureInfo</code> object. + * + * @param createTransformsInfoProfiles The + * <code>CreateTransformsInfoProfile</code> object from which to extract the + * transformation supplements. + * @return A <code>List</code> of <code>DataObject</code>s containing the + * transformation supplements. + * @throws MOASystemException A system error occurred creating one of the + * transformation supplements. + * @throws MOAApplicationException An error occurred creating one of the + * transformation supplements. + */ + private List buildTransformationSupplements(List createTransformsInfoProfiles) + throws MOASystemException, MOAApplicationException { + + List transformationSupplements = new ArrayList(); + DataObjectFactory factory = DataObjectFactory.getInstance(); + Iterator iter; + + for (iter = createTransformsInfoProfiles.iterator(); iter.hasNext();) { + CreateTransformsInfoProfileExplicit profile = + (CreateTransformsInfoProfileExplicit) iter.next(); + List supplements = profile.getSupplements(); + + if (supplements != null) { + Iterator supplIter; + + for (supplIter = supplements.iterator(); supplIter.hasNext();) { + XMLDataObjectAssociation supplement = + (XMLDataObjectAssociation) supplIter.next(); + + transformationSupplements.add( + factory.createFromXmlDataObjectAssociation( + supplement, + false, + true)); + } + } + } + + return transformationSupplements; + } + + /** + * Build the <code>List</code> of <code>DataObjectTreatment</code>s for the + * given <code>SingleSignatureInfo</code> object.. + * + * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object + * from which to exctract the <code>CreateTransformsInfoProfile</code>s + * containing the data for the <code>DataObjectTreatment</code>s. + * @param createTransformsInfoProfiles The + * <code>CreateTransformsInfoProfile</code>s contained in the + * <code>singleSignatureInfo</code>. + * @param transformationSupplements Additional parameters for + * transformations contained in <code>DataObjectTreatment</code>s. + * @return A <code>List</code> of <code>DataObjectTreatment</code> objects. + * @throws MOAApplicationException An error occurred building one of the + * <code>DataObjectTreatment</code>s. + * @throws MOASystemException A system error occurred building one of the + * <code>DataObjectTreatment</code>s. + */ + private List buildDataObjectTreatmentList( + SingleSignatureInfo singleSignatureInfo, + List createTransformsInfoProfiles, + List transformationSupplements) + throws MOASystemException, MOAApplicationException { + + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + List treatments = new ArrayList(); + List dataObjInfos = singleSignatureInfo.getDataObjectInfos(); + int dataObjectTreatmentCount = 1; + String hashAlgorithmName; + Iterator dtIter; + Iterator prIter; + + prIter = createTransformsInfoProfiles.iterator(); + for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) { + CreateTransformsInfoProfileExplicit profile = + (CreateTransformsInfoProfileExplicit) prIter.next(); + DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next(); + IdGenerator objIdGen = + new IdGenerator( + ("signed-data-" + createProfileCount) + + ("-" + dataObjectTreatmentCount++), + reserved); + DataObjectTreatmentImpl treatment = new DataObjectTreatmentImpl(objIdGen); + + treatment.setFinalContentType( + profile.getCreateTransformsInfo().getFinalDataMetaInfo().getMimeType()); + treatment.setTransformationList(buildTransformationList(profile)); + treatment.setReferenceInManifest(dataObjInfo.isChildOfManifest()); + + hashAlgorithmName = + (String) HASH_ALGORITHM_MAPPING.get( + config.getDigestMethodAlgorithmName()); + if (hashAlgorithmName == null) { + error( + "config.17", + new Object[] { config.getDigestMethodAlgorithmName()}); + throw new MOASystemException("2900", null); + } + + treatment.setHashAlgorithmName(hashAlgorithmName); + treatment.setIncludedInSignature( + DataObjectInfo.STRUCTURE_ENVELOPING.equals(dataObjInfo.getStructure())); + treatment.setTransformationSupplements(transformationSupplements); + + treatments.add(treatment); + + } + + return treatments; + } + + /** + * Build the <code>List</code> of transformations contained in a + * <code>CreateTransformsInfoProfile</code> object. + * + * @param profile The <code>CreateTransformsInfoProfile</code> object + * from which to extract the <code>Transform</code>s. + * @return A <code>List</code> of <code>Transformation</code>s contained in + * the given <code>CreateTransformsInfoProfile</code>. + * @throws MOAApplicationException An error occurred building one of the + * <code>Transformation</code>s. + */ + private List buildTransformationList(CreateTransformsInfoProfileExplicit profile) + throws MOAApplicationException { + + TransformationFactory factory = TransformationFactory.getInstance(); + List transforms = profile.getCreateTransformsInfo().getTransforms(); + + return transforms != null + ? factory.createTransformationList(transforms) + : Collections.EMPTY_LIST; + } + + /** + * Build the set of <code>KeyEntryID</code>s available to the given + * <code>keyGroupID</code>. + * + * @param keyGroupID The keygroup ID for which the available keys should be + * returned. + * @return The <code>Set</code> of <code>KeyEntryID</code>s + * identifying the available keys. + */ + private Set buildKeySet(String keyGroupID) { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + Set keyGroupEntries; + + // get the KeyGroup entries from the configuration + if (context.getClientCertificate() != null) { + X509Certificate cert = context.getClientCertificate()[0]; + Principal issuer = cert.getIssuerDN(); + BigInteger serialNumber = cert.getSerialNumber(); + + keyGroupEntries = + config.getKeyGroupEntries(issuer, serialNumber, keyGroupID); + } else { + keyGroupEntries = config.getKeyGroupEntries(null, null, keyGroupID); + } + + // map the KeyGroup entries to a set of KeyEntryIDs + if (keyGroupEntries == null) { + return null; + } else if (keyGroupEntries.size() == 0) { + return Collections.EMPTY_SET; + } else { + KeyModule module = + KeyModuleFactory.getInstance( + new TransactionId(context.getTransactionID())); + Set keyEntryIDs = module.getPrivateKeyEntryIDs(); + Set keySet = new HashSet(); + Iterator iter; + + // filter out the keys that do not exist in the IAIK configuration + // by walking through the key entries and checking if the exist in the + // keyGroupEntries + for (iter = keyEntryIDs.iterator(); iter.hasNext();) { + KeyEntryID entryID = (KeyEntryID) iter.next(); + KeyGroupEntry entry = + new KeyGroupEntry( + entryID.getModuleID(), + entryID.getCertificateIssuer(), + entryID.getCertificateSerialNumber()); + if (keyGroupEntries.contains(entry)) { + keySet.add(entryID); + } + } + return keySet; + } + } + + /** + * Get the signature location index where the signature will be inserted into + * the signature parent element. + * + * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object + * containing the <code>CreateSignatureLocation</code>. + * @return The index at which to insert the signature into the signature + * environment. + * @throws MOAApplicationException An error occurred parsing the + * <code>CreateSignatureEnvironmentProfile</code>. + */ + private XMLSignatureInsertionLocation getSignatureInsertionLocationIndex(SingleSignatureInfo singleSignatureInfo) + throws MOAApplicationException { + + CreateSignatureInfo createInfo = + singleSignatureInfo.getCreateSignatureInfo(); + + if (createInfo != null) { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + CreateSignatureEnvironmentProfileExplicit profile = + ProfileMapper.mapCreateSignatureEnvironmentProfile( + createInfo.getCreateSignatureEnvironmentProfile(), + config); + int index = profile.getCreateSignatureLocation().getIndex(); + + return new XMLSignatureInsertionLocationImpl(index); + } else { + return new XMLSignatureInsertionLocationImpl(0); + } + } + + /** + * Utility function to issue an error message to the log. + * + * @param messageId The ID of the message to log. + * @param parameters Additional message parameters. + */ + private static void error(String messageId, Object[] parameters) { + MessageProvider msg = MessageProvider.getInstance(); + + Logger.error(new LogMsg(msg.getMessage(messageId, parameters))); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java new file mode 100644 index 000000000..b8af3c02a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java @@ -0,0 +1,580 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import iaik.IAIKException; +import iaik.IAIKRuntimeException; +import iaik.server.modules.xml.DataObject; +import iaik.server.modules.xml.XMLDataObject; +import iaik.server.modules.xml.XMLSignature; +import iaik.server.modules.xmlsign.XMLConstants; +import iaik.server.modules.xmlverify.DsigManifest; +import iaik.server.modules.xmlverify.ReferenceData; +import iaik.server.modules.xmlverify.SecurityLayerManifest; +import iaik.server.modules.xmlverify.XMLSignatureVerificationModule; +import iaik.server.modules.xmlverify.XMLSignatureVerificationModuleFactory; +import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile; +import iaik.server.modules.xmlverify.XMLSignatureVerificationResult; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.logging.LoggingContext; +import at.gv.egovernment.moa.logging.LoggingContextManager; +import at.gv.egovernment.moa.util.CollectionUtils; +import at.gv.egovernment.moa.util.Constants; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterHash; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.xml.XMLSignatureImpl; +import at.gv.egovernment.moa.spss.server.logging.IaikLog; +import at.gv.egovernment.moa.spss.server.logging.TransactionId; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A class providing a DOM based interface to the + * <code>XMLSignatureVerificationModule</code>. + * + * This class performs the invocation of the + * <code>iaik.server.modules.xmlverify.XMLSignatureVerificationModule</code> + * from a <code>VerifyXMLSignatureRequest</code> given as a DOM element. The + * result of the invocation is integrated into a + * <code>VerifyXMLSignatureResponse</code> and returned. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureVerificationInvoker { + + /** The single instance of this class. */ + private static XMLSignatureVerificationInvoker instance = null; + + private static Set FILTERED_REF_TYPES; + + static { + FILTERED_REF_TYPES = new HashSet(); + FILTERED_REF_TYPES.add(DsigManifest.XML_DSIG_MANIFEST_TYPE); + FILTERED_REF_TYPES.add(SecurityLayerManifest.SECURITY_LAYER_MANIFEST_TYPE); + FILTERED_REF_TYPES.add( + SecurityLayerManifest.SECURITY_LAYER_MANIFEST_TYPE_OLD); + FILTERED_REF_TYPES.add( + XMLConstants.NAMESPACE_ETSI_STRING + "SignedProperties"); + } + + /** + * Get the single instance of this class. + * + * @return The single instance of this class. + */ + public static synchronized XMLSignatureVerificationInvoker getInstance() { + if (instance == null) { + instance = new XMLSignatureVerificationInvoker(); + } + return instance; + } + + /** + * Create a new <code>XMLSignatureCreationInvoker</code>. + * + * Protected to disallow multiple instances. + */ + protected XMLSignatureVerificationInvoker() { + } + + /** + * Process the <code>VerifyXMLSignatureRequest<code> message and invoke the + * <code>XMLSignatureVerificationModule</code>. + * + * @param request A <code>VerifyXMLSignatureRequest<code> API object + * containing the data for verifying an XML signature. + * @return A <code>VerifyXMLSignatureResponse</code> containing the + * answert to the <code>VerifyXMLSignatureRequest</code>. + * MOA schema definition. + * @throws MOAException An error occurred during signature verification. + */ + public VerifyXMLSignatureResponse verifyXMLSignature(VerifyXMLSignatureRequest request) + throws MOAException { + + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + LoggingContext loggingCtx = + LoggingContextManager.getInstance().getLoggingContext(); + XMLSignatureVerificationProfileFactory profileFactory = + new XMLSignatureVerificationProfileFactory(request); + VerifyXMLSignatureResponseBuilder responseBuilder = + new VerifyXMLSignatureResponseBuilder(); + XMLSignatureVerificationResult result; + XMLSignatureVerificationProfile profile; + ReferencesCheckResult signatureManifestCheck; + DataObjectFactory dataObjFactory; + XMLDataObject signatureEnvironment; + Node signatureEnvironmentParent = null; + Element requestElement = null; + XMLSignature xmlSignature; + Date signingTime; + List supplements; + List dataObjectList; + + // get the supplements + supplements = getSupplements(request); + + // build XMLSignature + dataObjFactory = DataObjectFactory.getInstance(); + signatureEnvironment = + dataObjFactory.createSignatureEnvironment( + request.getSignatureInfo().getVerifySignatureEnvironment(), + supplements); + xmlSignature = buildXMLSignature(signatureEnvironment, request); + + // build the list of DataObjects + dataObjectList = buildDataObjectList(supplements); + + // build profile + profile = profileFactory.createProfile(); + + // get the signingTime + signingTime = request.getDateTime(); + + // make the signature environment the root of the document, if it is not a + // separate document anyway; this is done to assure that canonicalization + // of the signature environment contains the correct namespace declarations + requestElement = + signatureEnvironment.getElement().getOwnerDocument().getDocumentElement(); + if (requestElement != signatureEnvironment.getElement()) { + signatureEnvironmentParent = + signatureEnvironment.getElement().getParentNode(); + requestElement.getOwnerDocument().replaceChild( + signatureEnvironment.getElement(), + requestElement); + } + + // verify the signature + try { + XMLSignatureVerificationModule module = + XMLSignatureVerificationModuleFactory.getInstance(); + + module.setLog(new IaikLog(loggingCtx.getNodeID())); + + result = + module.verifySignature( + xmlSignature, + dataObjectList, + profile, + signingTime, + new TransactionId(context.getTransactionID())); + } catch (IAIKException e) { + MOAException moaException = IaikExceptionMapper.getInstance().map(e); + throw moaException; + } catch (IAIKRuntimeException e) { + MOAException moaException = IaikExceptionMapper.getInstance().map(e); + throw moaException; + } + + // swap back in the request as root document + if (requestElement != signatureEnvironment.getElement()) { + requestElement.getOwnerDocument().replaceChild( + requestElement, + signatureEnvironment.getElement()); + signatureEnvironmentParent.appendChild(signatureEnvironment.getElement()); + } + + // check the result + signatureManifestCheck = + validateSignatureManifest(request, result, profile); + + // build the response + responseBuilder.setResult(result, profile, signatureManifestCheck); + + return responseBuilder.getResponse(); + } + + /** + * Select the <code>dsig:Signature</code> DOM element within the signature + * environment. + * + * @param signatureEnvironment The signature environment containing the + * <code>dsig:Signature</code>. + * @param request The <code>VerifyXMLSignatureRequest</code> containing the + * signature environment. + * @return The <code>dsig:Signature</code> element wrapped in a + * <code>XMLSignature</code> object. + * @throws MOAApplicationException An error occurred locating the + * <code>dsig:Signature</code>. + */ + private XMLSignature buildXMLSignature( + XMLDataObject signatureEnvironment, + VerifyXMLSignatureRequest request) + throws MOAApplicationException { + + VerifySignatureLocation signatureLocation = + request.getSignatureInfo().getVerifySignatureLocation(); + Element signatureParent; + + // evaluate the VerifySignatureLocation to get the signature parent + signatureParent = + InvokerUtils.evaluateSignatureLocation( + signatureEnvironment.getElement(), + signatureLocation); + + // check for signatureParent to be a dsig:Signature element + if (!"Signature".equals(signatureParent.getLocalName()) + || !Constants.DSIG_NS_URI.equals(signatureParent.getNamespaceURI())) { + throw new MOAApplicationException("2266", null); + } + + return new XMLSignatureImpl(signatureParent); + } + + /** + * Build the supplemental data objects contained in the + * <code>VerifyXMLSignatureRequest</code>. + * + * @param supplements A <code>List</code> of + * <code>XMLDataObjectAssociation</code>s containing the supplement data. + * @return A <code>List</code> of <code>DataObject</code>s representing the + * supplemental data objects. + * @throws MOASystemException A system error occurred building one of the data + * objects. + * @throws MOAApplicationException An error occurred building one of the data + * objects. + */ + private List buildDataObjectList(List supplements) + throws MOASystemException, MOAApplicationException { + List dataObjectList = new ArrayList(); + + DataObjectFactory factory = DataObjectFactory.getInstance(); + DataObject dataObject; + Iterator iter; + + for (iter = supplements.iterator(); iter.hasNext();) { + XMLDataObjectAssociation supplement = + (XMLDataObjectAssociation) iter.next(); + dataObject = + factory.createFromXmlDataObjectAssociation(supplement, true, false); + dataObjectList.add(dataObject); + } + + return dataObjectList; + } + + /** + * Get the supplemental data contained in the + * <code>VerifyXMLSignatureRequest</code>. + * + * @param request The <code>VerifyXMLSignatureRequest</code> containing the + * supplemental data. + * @return A <code>List</code> of <code>XMLDataObjectAssociation</code> + * objects containing the supplemental data. + * @throws MOAApplicationException An error occurred resolving one of the + * supplement profiles. + */ + private List getSupplements(VerifyXMLSignatureRequest request) + throws MOAApplicationException { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + List supplementProfiles = request.getSupplementProfiles(); + + if (supplementProfiles != null) { + List supplements = new ArrayList(); + List mappedProfiles = + ProfileMapper.mapSupplementProfiles(supplementProfiles, config); + Iterator iter; + + for (iter = mappedProfiles.iterator(); iter.hasNext();) { + SupplementProfileExplicit profile = + (SupplementProfileExplicit) iter.next(); + supplements.add(profile.getSupplementProfile()); + } + + return supplements; + } + + return null; + } + + /** + * Perform additional validations of the + * <code>XMLSignatureVerificationResult</code>. + * + * <p> In particular, it is verified that: + * <ul> + * <li>Each <code>ReferenceData</code> object contains transformation + * chain that matches one of the <code>Transforms</code> given in the + * corresponding <code>SignatureManifestCheckParams/ReferenceInfo</code></li> + * <li>The hash values of the <code>TransformParameter</code>s are valid. + * </li> + * </ul> + * </p> + * + * @param request The <code>VerifyXMLSignatureRequest</code> containing the + * signature to verify. + * @param result The result produced by + * <code>XMLSignatureVerificationModule</code>. + * @param profile The profile used for validating the <code>request</code>. + * @return The result of additional validations of the signature manifest. + * @throws MOAApplicationException Post-validation of the + * <code>XMLSignatureVerificaitonResult</code> failed. + */ + private ReferencesCheckResult validateSignatureManifest( + VerifyXMLSignatureRequest request, + XMLSignatureVerificationResult result, + XMLSignatureVerificationProfile profile) + throws MOAApplicationException { + + SPSSFactory factory = SPSSFactory.getInstance(); + MessageProvider msg = MessageProvider.getInstance(); + + // validate that each ReferenceData object contains transforms specified + // in the corresponding SignatureManifestCheckParams/ReferenceInfo + if (profile.checkSecurityLayerManifest()) { + List refInfos = + request.getSignatureManifestCheckParams().getReferenceInfos(); + List refDatas = filterReferenceInfos(result.getReferenceDataList()); + List failedReferencesList = new ArrayList(); + Iterator refInfoIter; + Iterator refDataIter; + + if (refInfos.size() != refDatas.size()) { + return factory.createReferencesCheckResult(1, null); + } + + refInfoIter = refInfos.iterator(); + refDataIter = + filterReferenceInfos(result.getReferenceDataList()).iterator(); + + while (refInfoIter.hasNext()) { + ReferenceInfo refInfo = (ReferenceInfo) refInfoIter.next(); + ReferenceData refData = (ReferenceData) refDataIter.next(); + List transforms = buildTransformsList(refInfo); + boolean found = false; + Iterator trIter; + + for (trIter = transforms.iterator(); trIter.hasNext() && !found;) { + found = trIter.next().equals(refData.getTransformationList()); + } + + if (!found) { + Integer refIndex = new Integer(refData.getReferenceIndex()); + String logMsg = + msg.getMessage("invoker.01", new Object[] { refIndex }); + + failedReferencesList.add(refIndex); + Logger.debug(new LogMsg(logMsg)); + } + } + + if (!failedReferencesList.isEmpty()) { + // at least one reference failed - return their indexes and check code 1 + int[] failedReferences = + CollectionUtils.toIntArray(failedReferencesList); + ReferencesCheckResultInfo checkInfo = + factory.createReferencesCheckResultInfo(null, failedReferences); + + return factory.createReferencesCheckResult(1, checkInfo); + } + } + + // validate the hashes contained in all the ReferenceInfo objects of the + // security layer manifest + if (profile.checkSecurityLayerManifest() + && result.containsSecurityLayerManifest()) { + Map hashValues = buildTransformParameterHashValues(request); + Set transformParameterURIs = + buildTransformParameterURIs(profile.getTransformationSupplements()); + List referenceInfoList = + result.getSecurityLayerManifest().getReferenceInfoList(); + Iterator refIter; + + for (refIter = referenceInfoList.iterator(); refIter.hasNext();) { + iaik.server.modules.xmlverify.ReferenceInfo ref = + (iaik.server.modules.xmlverify.ReferenceInfo) refIter.next(); + byte[] hash = (byte[]) hashValues.get(ref.getURI()); + + if (!transformParameterURIs.contains(ref.getURI()) + || (hash != null && !Arrays.equals(hash, ref.getHashValue()))) { + + // the transform parameter doesn't exist or the hashs do not match + // return the index of the failed reference and check code 1 + int[] failedReferences = new int[] { ref.getReferenceIndex()}; + ReferencesCheckResultInfo checkInfo = + factory.createReferencesCheckResultInfo(null, failedReferences); + String logMsg = + msg.getMessage( + "invoker.02", + new Object[] { new Integer(ref.getReferenceIndex())}); + + Logger.debug(new LogMsg(logMsg)); + + return factory.createReferencesCheckResult(1, checkInfo); + } + } + } + + return factory.createReferencesCheckResult(0, null); + } + + /** + * Get all <code>Transform</code>s contained in all the + * <code>VerifyTransformsInfoProfile</code>s of the given + * <code>ReferenceInfo</code>. + * + * @param refInfo The <code>ReferenceInfo</code> object containing + * the transformations. + * @return A <code>List</code> of <code>List</code>s. Each of the + * <code>List</code>s contains <code>Transformation</code> objects. + * @throws MOAApplicationException An error occurred building one of the + * <code>Transformation</code>s. + */ + private List buildTransformsList(ReferenceInfo refInfo) + throws MOAApplicationException { + + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + List profiles = refInfo.getVerifyTransformsInfoProfiles(); + List mappedProfiles = + ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config); + List transformsList = new ArrayList(); + TransformationFactory factory = TransformationFactory.getInstance(); + Iterator iter; + + for (iter = mappedProfiles.iterator(); iter.hasNext();) { + VerifyTransformsInfoProfileExplicit profile = + (VerifyTransformsInfoProfileExplicit) iter.next(); + List transforms = profile.getTransforms(); + + if (transforms != null) { + transformsList.add(factory.createTransformationList(transforms)); + } + } + + return transformsList; + } + + /** + * Build the <code>Set</code> of all <code>TransformParameter</code> URIs. + * + * @param transformParameters The <code>List</code> of + * <code>TransformParameter</code>s, as provided to the verification. + * @return The <code>Set</code> of all <code>TransformParameter</code> URIs. + */ + private Set buildTransformParameterURIs(List transformParameters) { + Set uris = new HashSet(); + Iterator iter; + + for (iter = transformParameters.iterator(); iter.hasNext();) { + DataObject transformParameter = (DataObject) iter.next(); + uris.add(transformParameter.getURI()); + } + + return uris; + } + + /** + * Build a mapping between <code>TransformParameter</code> URIs (a + * <code>String</code> and <code>dsig:HashValue</code> (a + * <code>byte[]</code>). + * + * @param request The <code>VerifyXMLSignatureRequest</code>. + * @return Map The resulting mapping. + * @throws MOAApplicationException An error occurred accessing one of + * the profiles. + */ + private Map buildTransformParameterHashValues(VerifyXMLSignatureRequest request) + throws MOAApplicationException { + + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + Map hashValues = new HashMap(); + List refInfos = + request.getSignatureManifestCheckParams().getReferenceInfos(); + Iterator refIter; + + for (refIter = refInfos.iterator(); refIter.hasNext();) { + ReferenceInfo refInfo = (ReferenceInfo) refIter.next(); + List profiles = refInfo.getVerifyTransformsInfoProfiles(); + List mappedProfiles = + ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config); + Iterator prIter; + + for (prIter = mappedProfiles.iterator(); prIter.hasNext();) { + VerifyTransformsInfoProfileExplicit profile = + (VerifyTransformsInfoProfileExplicit) prIter.next(); + List trParameters = profile.getTransformParameters(); + Iterator trIter; + + for (trIter = trParameters.iterator(); trIter.hasNext();) { + TransformParameter transformParameter = + (TransformParameter) trIter.next(); + String uri = transformParameter.getURI(); + + if (transformParameter.getTransformParameterType() + == TransformParameter.HASH_TRANSFORMPARAMETER) { + hashValues.put( + uri, + ((TransformParameterHash) transformParameter).getDigestValue()); + } + + } + } + } + return hashValues; + } + + /** + * Filter the <code>ReferenceInfo</code>s returned by the + * <code>VerifyXMLSignatureResult</code> for comparison with the + * <code>ReferenceInfo</code> elements in the request. + * + * @param referenceInfos The <code>ReferenceInfo</code>s from the + * <code>VerifyXMLSignatureResult</code>. + * @return A <code>List</code> of all <code>ReferenceInfo</code>s whose type + * is not a XMLDsig manifest, Security Layer manifest, or ETSI signed + * property. + */ + private List filterReferenceInfos(List referenceInfos) { + List filtered = new ArrayList(); + Iterator iter; + + for (iter = referenceInfos.iterator(); iter.hasNext();) { + iaik.server.modules.xmlverify.ReferenceInfo refInfo = + (iaik.server.modules.xmlverify.ReferenceInfo) iter.next(); + String refType = refInfo.getReferenceType(); + + if (refType == null || !FILTERED_REF_TYPES.contains(refType)) { + filtered.add(refInfo); + } + } + + return filtered; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java new file mode 100644 index 000000000..858964c82 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java @@ -0,0 +1,147 @@ +package at.gv.egovernment.moa.spss.server.invoke; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile; + +import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams; +import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.pki.PKIProfileImpl; +import at.gv.egovernment.moa.spss.server.iaik.xmlverify.XMLSignatureVerificationProfileImpl; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; + +/** + * A factory to create a <code>XMLSignatureVerificationProfile</code> from a + * <code>VerifyXMLSignatureRequest</code>, based on the current MOA + * configuration. + * + * @author Patrick Peck + * @version $Id$ + */ +public class XMLSignatureVerificationProfileFactory { + + /** The <code>VerifyXMLSignatureRequest</code> for which to create profile + * information. */ + private VerifyXMLSignatureRequest request; + + /** + * Create a new <code>XMLSignatureVerificationProfileFactory</code>. + * + * @param request The <code>VerifyXMLSignatureRequest</code> to extract + * profile data from. + */ + public XMLSignatureVerificationProfileFactory(VerifyXMLSignatureRequest request) { + this.request = request; + } + + /** + * Create a <code>XMLSignatureCreationProfile</code> from the + * <code>VerifyXMLSignaturesRequest</code> and the current MOA configuration. + * + * @return The <code>XMLSignatureVerificationProfile</code> containing + * additional information for verifying an XML signature. + * @throws MOASystemException A system error occurred building the profile. + * @throws MOAApplicationException An error occurred building the profile. + */ + public XMLSignatureVerificationProfile createProfile() + throws MOASystemException, MOAApplicationException { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + XMLSignatureVerificationProfileImpl profile = + new XMLSignatureVerificationProfileImpl(); + SignatureManifestCheckParams checkParams; + String trustProfileID; + + // set whether to check XMLDsig manifests + profile.setCheckXMLDsigManifests(true); + + // set the certificate validation profile + trustProfileID = request.getTrustProfileId(); + profile.setCertificateValidationProfile( + new PKIProfileImpl(config, trustProfileID)); + + // set whether hash input data is to be included + profile.setIncludeHashInputData(request.getReturnHashInputData()); + + // set the security layer manifest check parameters + checkParams = request.getSignatureManifestCheckParams(); + if (checkParams != null) { + List transformationSupplements; + + profile.setCheckSecurityLayerManifest(true); + profile.setIncludeReferenceInputData( + checkParams.getReturnReferenceInputData()); + transformationSupplements = buildTransformationSupplements(); + profile.setTransformationSupplements(transformationSupplements); + } else { + profile.setCheckSecurityLayerManifest(false); + profile.setIncludeReferenceInputData(false); + profile.setTransformationSupplements(Collections.EMPTY_LIST); + } + + return profile; + } + + /** + * Build supplemental data objects used in the transformations. + * + * @return A <code>List</code> of <code>DataObject</code>s providing + * supplemental data to the transformations. + * @throws MOASystemException A system error occurred building one of the + * transformations. + * @throws MOAApplicationException An error occurred building one of the + * transformations. + */ + public List buildTransformationSupplements() + throws MOASystemException, MOAApplicationException { + TransactionContext context = + TransactionContextManager.getInstance().getTransactionContext(); + ConfigurationProvider config = context.getConfiguration(); + SignatureManifestCheckParams checkParams = + request.getSignatureManifestCheckParams(); + List transformsProfiles = new ArrayList(); + List transformationSupplements = new ArrayList(); + DataObjectFactory factory = DataObjectFactory.getInstance(); + List refInfos = checkParams.getReferenceInfos(); + Iterator refIter; + Iterator prIter; + Iterator trIter; + + // build the list of all VerifyTransformsInfoProfiles in all ReferenceInfos + refInfos = checkParams.getReferenceInfos(); + for (refIter = refInfos.iterator(); refIter.hasNext();) { + ReferenceInfo refInfo = (ReferenceInfo) refIter.next(); + List profiles = refInfo.getVerifyTransformsInfoProfiles(); + + transformsProfiles.addAll( + ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config)); + } + + // build the DataObjects + for (prIter = transformsProfiles.iterator(); prIter.hasNext();) { + VerifyTransformsInfoProfileExplicit profile = + (VerifyTransformsInfoProfileExplicit) prIter.next(); + List transformParameters = profile.getTransformParameters(); + + for (trIter = transformParameters.iterator(); trIter.hasNext();) { + TransformParameter trParam = (TransformParameter) trIter.next(); + transformationSupplements.add( + factory.createFromTransformParameter(trParam)); + } + } + + return transformationSupplements; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLog.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLog.java new file mode 100644 index 000000000..068fab5ca --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLog.java @@ -0,0 +1,126 @@ +package at.gv.egovernment.moa.spss.server.logging; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import iaik.logging.TransactionId; + +/** + * An implementation of the <code>iaik.logging.Log</code> + * interface that is based on Jakarta Commons-Logging. + * + * @author Fatemeh Philippi + * @version $Id$ + */ +public class IaikLog implements iaik.logging.Log { + /** The hierarchy to log all IAIK output to. */ + public static final String IAIK_LOG_HIERARCHY = "iaik.server"; + /** The commons-loggin <code>Log</code> to use for logging the messages. */ + private static Log log = LogFactory.getLog(IAIK_LOG_HIERARCHY); + /** The node ID to use. */ + private String nodeId; + + /** + * Create a new <code>IaikLog</code>. + * + * @param nodeId The node ID for this <code>Log</code> object. + */ + public IaikLog(String nodeId) { + this.nodeId = nodeId; + } + + /** + * @see iaik.logging.Log#isDebugEnabled() + */ + public boolean isDebugEnabled() { + return log.isDebugEnabled(); + } + + /** + * @see iaik.logging.Log#debug(TransactionId, Object, Throwable) + */ + public void debug(TransactionId transactionId, Object message, Throwable t) { + IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message); + + log.debug(msg, t); + } + + /** + * @see iaik.logging.Log#isInfoEnabled() + */ + public boolean isInfoEnabled() { + return log.isInfoEnabled(); + } + + /** + * @see iaik.logging.Log#info(TransactionId, Object, Throwable) + */ + public void info(TransactionId transactionId, Object message, Throwable t) { + IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message); + + log.info(msg, t); + } + + /** + * @see iaik.logging.Log#isWarnEnabled() + */ + public boolean isWarnEnabled() { + return log.isWarnEnabled(); + } + + /** + * @see iaik.logging.Log#warn(TransactionId, Object, Throwable) + */ + public void warn(TransactionId transactionId, Object message, Throwable t) { + IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message); + + log.warn(msg, t); + } + + /** + * @see iaik.logging.Log#isErrorEnabled() + */ + public boolean isErrorEnabled() { + return log.isErrorEnabled(); + } + + /** + * @see iaik.logging.Log#error(TransactionId, Object, Throwable) + */ + public void error(TransactionId transactionId, Object message, Throwable t) { + IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message); + + log.error(msg, t); + } + + /** + * @see iaik.logging.Log#isFatalEnabled() + */ + public boolean isFatalEnabled() { + return log.isFatalEnabled(); + } + + /** + * @see iaik.logging.Log#fatal(TransactionId, Object, Throwable) + */ + public void fatal(TransactionId transactionId, Object message, Throwable t) { + IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message); + + log.fatal(msg, t); + } + + /** + * @see iaik.logging.Log#setNodeId(String) + */ + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + /** + * @see iaik.logging.Log#getNodeId() + */ + public String getNodeId() { + return nodeId; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogFactory.java new file mode 100644 index 000000000..a0e4def86 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogFactory.java @@ -0,0 +1,42 @@ +package at.gv.egovernment.moa.spss.server.logging; + +import iaik.logging.Log; +import iaik.logging.LogConfigurationException; +import iaik.logging.LogFactory; + +import at.gv.egovernment.moa.logging.LoggingContextManager; + +/** + * An implementation of the <code>iaik.logging.LogFactory</code> abstract + * class to log messages to the MOA logging subsystem. + * + * @author Patrick Peck + * @version $Id$ + */ +public class IaikLogFactory extends LogFactory { + + public Log getInstance(Class clazz) throws LogConfigurationException { + return getInstanceImpl(); + } + + public Log getInstance(String name) throws LogConfigurationException { + return getInstanceImpl(); + } + + /** + * Return an instance of <code>iaik.logging.Log</code>. + * + * @return The <code>iaik.logging.Log</code> object to log messages to. + */ + private Log getInstanceImpl() { + String nodeID = + LoggingContextManager.getInstance().getLoggingContext().getNodeID(); + + return new IaikLog(nodeID); + } + + public void release() { + // we do not hold any resources + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogMsg.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogMsg.java new file mode 100644 index 000000000..75fb388a9 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogMsg.java @@ -0,0 +1,54 @@ +package at.gv.egovernment.moa.spss.server.logging; + +import iaik.logging.TransactionId; + +/** + * A unified message type to log messages from the IAIK subsystem. + * + * @author Patrick Peck + * @version $Id$ + */ +public class IaikLogMsg { + + /** The transaction ID of this message. */ + private TransactionId transactionId; + /** The node ID of this message. */ + private String nodeId; + /** The message to log. */ + private Object message; + + /** + * Create a <code>IaikLogMsg</code> object. + * + * @param transactionId The transaction id of the transaction which + * generated this log message. May be <code>null</code>. + * @param nodeId The node id where this message was generated. May be + * <code>null</code>. + * @param message The actual message to log. May be <code>null</code>. + */ + public IaikLogMsg(TransactionId transactionId, String nodeId, Object message) { + this.transactionId = transactionId; + this.nodeId = nodeId; + this.message = message; + } + + + /** + * Convert this log message to a <code>String</code>. + * + * @return The <code>String</code> representation of this log message. + */ + public String toString() { + StringBuffer msg = new StringBuffer(); + + msg.append("TID="); + msg.append(transactionId != null ? transactionId.getLogID() : "<null>"); + msg.append(" NID="); + msg.append(nodeId != null ? nodeId : "<null>"); + msg.append(" MSG="); + msg.append(message != null ? message.toString() : "<null>"); + + return msg.toString(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/TransactionId.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/TransactionId.java new file mode 100644 index 000000000..9e0239464 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/TransactionId.java @@ -0,0 +1,38 @@ +package at.gv.egovernment.moa.spss.server.logging; + +/** + * An implementation of the <code>iaik.logging.TransactionId</code> interface. + * + * @author Patrick Peck + * @version $Id$ + */ +public class TransactionId implements iaik.logging.TransactionId { + + /** The String representation for logging the transaction ID. */ + private String logID; + + /** + * Create a <code>TransactionId</code> object. + * + * @param logID The transaction id as it should be presented to the logging + * subsystem. + */ + public TransactionId(String logID) { + this.logID = logID; + } + + /** + * @see iaik.logging.TransactionId#getLogID() + */ + public String getLogID() { + return logID; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return getLogID(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java new file mode 100644 index 000000000..9d6b255c2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java @@ -0,0 +1,252 @@ +package at.gv.egovernment.moa.spss.server.service; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.cert.X509Certificate; + +import javax.servlet.http.HttpServletRequest; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.axis.AxisFault; +import org.apache.axis.MessageContext; +import org.apache.axis.handlers.BasicHandler; +import org.apache.axis.transport.http.HTTPConstants; +import org.apache.axis.utils.Messages; +import org.apache.axis.utils.XMLUtils; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.logging.LoggingContext; +import at.gv.egovernment.moa.logging.LoggingContextManager; + +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; +import at.gv.egovernment.moa.spss.server.transaction.TransactionIDGenerator; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * An handler that is invoked on each web service request and performs some + * central message handling. + * + * Mainly sets up the <code>TransactionContext</code> for the current + * transaction (i.e. web service request). + * + * @author Patrick Peck + * @author Stefan Knirsch + * @version $Id$ + */ +public class AxisHandler extends BasicHandler { + + /** The property name for accessing the HTTP request. */ + private static final String REQUEST_PROPERTY = + HTTPConstants.MC_HTTP_SERVLETREQUEST; + /** The property name for accessing the X509 client certificate chain. */ + private static final String X509_CERTIFICATE_PROPERTY = + "javax.servlet.request.X509Certificate"; + /** The property name for accessing the SOAP action header. */ + private static final String SOAP_ACTION_HEADER = "soapaction"; + + /** + * Handle an invocation of this handler. + * + * @param msgContext Information about this request/response. + * @throws AxisFault An error occurred during processing of the request. + * @see org.apache.axis.Handler#invoke(MessageContext) + */ + public void invoke(MessageContext msgContext) throws AxisFault { + if (!msgContext.getPastPivot()) { + handleRequest(msgContext); + } else { + handleResponse(msgContext); + } + } + + /** + * This method is called by <code>invoke</code> to handle incoming requests. + * + * @param msgContext The context as provided to <code>invoke</code>. + * @throws AxisFault An error occurred during processing of the request. + */ + private void handleRequest(MessageContext msgContext) throws AxisFault { + try { + // generate a unique transaction id and build the TransactionContext + // for this request + HttpServletRequest request = + (HttpServletRequest) msgContext.getProperty(REQUEST_PROPERTY); + + X509Certificate[] clientCert = + (X509Certificate[]) request.getAttribute(X509_CERTIFICATE_PROPERTY); + + ConfigurationProvider configuration = + ConfigurationProvider.getInstance(); + + TransactionContext context = + new TransactionContext( + TransactionIDGenerator.nextID(), + clientCert, + configuration); + + context.setRequestName((String) request.getHeader(SOAP_ACTION_HEADER)); + + setUpContexts(context); + + // log some information about the request + info( + "handler.00", + new Object[] { + context.getTransactionID(), + msgContext.getTargetService()}); + info("handler.01", new Object[] { request.getRemoteAddr()}); + if (clientCert != null) { + info( + "handler.02", + new Object[] { + clientCert[0].getSubjectDN(), + clientCert[0].getSerialNumber(), + clientCert[0].getIssuerDN()}); + + } else { + info("handler.03", null); + } + if (Logger.isDebugEnabled()) { + String msg = msgContext.getCurrentMessage().getSOAPPartAsString(); + Logger.debug(new LogMsg(msg)); + } + } catch (MOASystemException e) { + MOASystemException se = new MOASystemException("2900", null, e); + AxisFault fault = AxisFault.makeFault(se); + fault.setFaultDetail(new Element[] { se.toErrorResponse()}); + throw fault; + } catch (Throwable t) { + MOASystemException e = new MOASystemException("2900", null, t); + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } + } + + /** + * This method is called by <code>invoke</code> to handle outgoing + * responses. + * + * @param msgContext The context as provided to <code>invoke</code>. + * @throws AxisFault An error occurred during processing of the response. + */ + private void handleResponse(MessageContext msgContext) throws AxisFault { + info("handler.04", null); + if (Logger.isDebugEnabled()) { + String msg = msgContext.getCurrentMessage().getSOAPPartAsString(); + Logger.debug(new LogMsg(msg)); + } + tearDownContexts(); + } + + /** + * Called, when the processing of the web service fails. + * + * @param msgContext Information about the current request. + * @see org.apache.axis.Handler#onFault(org.apache.axis.MessageContext) + */ + public void onFault(MessageContext msgContext) { + info("handler.05", null); + tearDownContexts(); + } + + /** + * Set up the thread-local contexts (<code>TransactionContext</code> and + * <code>LoggingContext</code>). + * + * @param context The <code>TransactionContext</code> to set for the current + * request. + */ + private void setUpContexts(TransactionContext context) { + // set the transaction context in the TransactionContextManager + TransactionContextManager tcm = TransactionContextManager.getInstance(); + tcm.setTransactionContext(context); + + // set the logging context in the LoggingContextManager + LoggingContextManager lcm = LoggingContextManager.getInstance(); + LoggingContext lc = new LoggingContext(context.getTransactionID()); + lcm.setLoggingContext(lc); + } + + /** + * Tear down the thread-local contexts. + */ + private void tearDownContexts() { + // unset the transaction context + TransactionContextManager tcm = TransactionContextManager.getInstance(); + tcm.setTransactionContext(null); + + // unset the logging context + LoggingContextManager lcm = LoggingContextManager.getInstance(); + lcm.setLoggingContext(null); + } + + /** + * Generate the WSDL into the <code>msgContext</code>. + * + * The code of this method is more or less copied from the + * <code>org.apache.axis.handlers.soap.SOAPService</code> class contained in + * the 1.1 release of Axis to allow for a missing <code>wsdlFile</code> (so + * that a resource by the same name is searched for in the classpath). The + * implementation of this method should be obsolete if Axis 1.1 or higher is + * used. + * + * @param msgContext The <code>MessageContext</code> that will contain the + * WSDL description of the current web service. + * @throws AxisFault An error occurred producing the WSDL. + */ + public void generateWSDL(MessageContext msgContext) throws AxisFault { + InputStream instream = null; + + // Got a WSDL file in the service description, so try and read it + try { + String filename = "/resources/wsdl/MOA-SP-SS-1.0-20020829.wsdl"; + msgContext.getService().getServiceDescription().getWSDLFile(); + File file = new File(filename); + if (file.exists()) { + //if this resolves to a file, load it + instream = new FileInputStream(filename); + } else { + //else load a named resource in our classloader. + instream = this.getClass().getResourceAsStream(filename); + if (instream == null) { + String errorText = Messages.getMessage("wsdlFileMissing", filename); + throw new AxisFault(errorText); + } + } + Document doc = XMLUtils.newDocument(instream); + msgContext.setProperty("WSDL", doc); + } catch (Exception e) { + throw AxisFault.makeFault(e); + } finally { + if (instream != null) { + try { + instream.close(); + } catch (IOException e) { + // ok to do nothing here + } + } + } + } + + /** + * Utility function to issue an info message to the log. + * + * @param messageId The ID of the message to log. + * @param parameters Additional message parameters. + */ + private static void info(String messageId, Object[] parameters) { + MessageProvider msg = MessageProvider.getInstance(); + + Logger.info(new LogMsg(msg.getMessage(messageId, parameters))); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/ConfigurationServlet.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ConfigurationServlet.java new file mode 100644 index 000000000..7783ed3f6 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ConfigurationServlet.java @@ -0,0 +1,120 @@ +package at.gv.egovernment.moa.spss.server.service; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.logging.LoggingContext; +import at.gv.egovernment.moa.logging.LoggingContextManager; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator; +import at.gv.egovernment.moa.spss.server.init.*; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A servlet to initialize and update the MOA configuration. + * + * @author Fatemeh Philippi + * @author Patrick Peck + * @version $Id$ + */ +public class ConfigurationServlet extends HttpServlet { + /** The document type of the HTML to generate. */ + private static final String DOC_TYPE = + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"; + + /** + * Handle a HTTP GET request, used to indicated that the MOA + * configuration needs to be updated (reloaded). + * + * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse) + */ + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + MessageProvider msg = MessageProvider.getInstance(); + PrintWriter out; + + // set up a logging context for logging the reconfiguration + LoggingContextManager.getInstance().setLoggingContext( + new LoggingContext("configuration update")); + + response.setContentType("text/html"); + out = response.getWriter(); + out.println(DOC_TYPE); + out.println("<head><title>MOA configuration update</title></head>"); + out.println("<body bgcolor=\"#FFFFFF\">"); + try { + // reconfigure the system + ConfigurationProvider config = ConfigurationProvider.reload(); + IaikConfigurator iaikConfigurator = new IaikConfigurator(); + + iaikConfigurator.configure(config); + + // print a status message + out.println("<p><b>" + msg.getMessage("config.06", null) + "</b></p>"); + Logger.info(new LogMsg(msg.getMessage("config.06", null))); + + if (!config.getWarnings().isEmpty()) { + // print the warnings + List allWarnings = new ArrayList(); + Iterator iter; + + allWarnings.addAll(config.getWarnings()); + allWarnings.addAll(iaikConfigurator.getWarnings()); + + out.println("<p><b>" + msg.getMessage("config.29", null) + "</b></p>"); + for (iter = allWarnings.iterator(); iter.hasNext();) { + out.println(iter.next() + "<br />"); + } + out.println("<p><b>" + msg.getMessage("config.28", null) + "</b></p>"); + } + + } catch (Throwable t) { + out.println("<p><b>" + msg.getMessage("config.20", null) + "</b></p>"); + out.println("<p><b>" + msg.getMessage("config.28", null) + "</b></p>"); + Logger.warn(new LogMsg(msg.getMessage("config.20", null)), t); + } + out.println("</body>"); + + out.flush(); + out.close(); + + // tear down the logging context + LoggingContextManager.getInstance().setLoggingContext(null); + } + + /** + * Do the same as <code>doGet</code>. + * + * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest, HttpServletResponse) + */ + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doGet(request, response); + } + + /** + * Perform some initial initialization tasks for the MOA web services + * application. + * + * Does an initial load of the MOA configuration to test if a working web + * service can be provided. + * + * @see javax.servlet.GenericServlet#init() + */ + public void init() throws ServletException { + SystemInitializer.init(); + } + +}
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/RevocationArchiveCleaner.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/RevocationArchiveCleaner.java new file mode 100644 index 000000000..997375305 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/RevocationArchiveCleaner.java @@ -0,0 +1,83 @@ +package at.gv.egovernment.moa.spss.server.service; + +import java.util.Date; + +import iaik.pki.revocation.RevocationSourceTypes; +import iaik.pki.store.revocation.archive.Archive; +import iaik.pki.store.revocation.archive.ArchiveFactory; + +import at.gv.egovernment.moa.logging.LogMsg; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.BoolUtils; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.logging.TransactionId; +import at.gv.egovernment.moa.spss.util.MessageProvider; + +/** + * A <code>Runnable</code> for periodically cleaning up the revocation archive. + * @author Patrick Peck + * @version $Id$ + */ +public class RevocationArchiveCleaner implements Runnable { + + /** The inverval between two clean-ups of the revocation archive. */ + private long archiveCleanupInterval; + + /** + * Create a new <code>RevocationArchiveCleaner</code>. + * + * @param archiveCleanupInterval The interval between two clean-ups of the + * revocation archive. + */ + public RevocationArchiveCleaner(long archiveCleanupInterval) { + this.archiveCleanupInterval = archiveCleanupInterval; + } + + /** + * Run the <code>RevocationArchiveCleaner</code> in its own + * <code>Thread</code>. + */ + public void run() { + while (true) { + try { + ConfigurationProvider config = + ConfigurationProvider.getInstance(); + String archiveInfo = + config.getGenericConfiguration( + ConfigurationProvider.ARCHIVE_REVOCATION_INFO_PROPERTY, + "false"); + + if (BoolUtils.valueOf(archiveInfo)) { + Archive archive = ArchiveFactory.getInstance().getArchive(); + long archiveDurationMillis = + (long) config.getCRLArchiveDuration() * 86400000; + + // delete old archive data + if (archiveDurationMillis > 0) { + Date olderThan = + new Date(System.currentTimeMillis() - archiveDurationMillis); + + archive.deleteOldArchiveEntries( + RevocationSourceTypes.CRL, + olderThan, + new TransactionId("RevocationArchiveCleaner")); + } + } + + } catch (Exception e) { + MessageProvider msg = MessageProvider.getInstance(); + Logger.error(new LogMsg(msg.getMessage("init.02", null)), e); + } + + // sleep + try { + Thread.sleep(archiveCleanupInterval * 1000); + } catch (InterruptedException e) { + // ok to do nothing here + } + + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/ServiceUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ServiceUtils.java new file mode 100644 index 000000000..4224f5665 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ServiceUtils.java @@ -0,0 +1,72 @@ +package at.gv.egovernment.moa.spss.server.service; + +import java.io.ByteArrayInputStream; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; + +import at.gv.egovernment.moa.spss.MOAApplicationException; + +/** + * Helper methods for the Service classes. + * + * @author Patrick Peck + * @version $Id$ + */ +public class ServiceUtils { + + /** + * Schema-validate a request. + * + * @param request The request to validate. + * @throws MOAApplicationException An error occurred validating the requst. + */ + public static void validateRequest(Element[] request) + throws MOAApplicationException { + + // validate the request + try { + DOMUtils.validateElement( + request[0], + Constants.ALL_SCHEMA_LOCATIONS, + null); + } catch (Exception e) { + throw new MOAApplicationException( + "1100", + new Object[] { e.getMessage()}, + e); + } + } + + /** + * Reparse the request with schema-validation turned on so that ID references + * are resolved. + * + * @param request The request to reparse. + * @return The reparsed request. + * @throws MOAApplicationException An error occurred parsing the request. + */ + public static Element reparseRequest(Element request) + throws MOAApplicationException { + + try { + byte[] requestBytes = DOMUtils.serializeNode(request, "UTF-8"); + Document validatedRequest = + DOMUtils.parseDocument( + new ByteArrayInputStream(requestBytes), + true, + Constants.ALL_SCHEMA_LOCATIONS, + null); + return validatedRequest.getDocumentElement(); + } catch (Exception e) { + throw new MOAApplicationException( + "1100", + new Object[] { e.getMessage()}, + e); + } + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java new file mode 100644 index 000000000..07d7ab371 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java @@ -0,0 +1,90 @@ +package at.gv.egovernment.moa.spss.server.service; + +import java.util.Collections; + +import javax.xml.namespace.QName; + +import org.w3c.dom.Element; + +import org.apache.axis.AxisFault; +import org.apache.axis.i18n.Messages; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureRequestParser; +import at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureResponseBuilder; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureCreationInvoker; + +/** + * The service endpoint for the <code>SignatureCreation</code> web service. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SignatureCreationService { + + /** + * Handle a <code>CreateXMLSignatureRequest</code>. + * + * @param request The <code>CreateXMLSignatureRequest</code> to work on + * (contained in the 0th element of the array). + * @return A <code>CreateXMLSignatureResponse</code> as the only element of + * the <code>Element</code> array. + * @throws AxisFault An error occurred during handling of the message. + */ + public Element[] CreateXMLSignatureRequest(Element[] request) + throws AxisFault { + XMLSignatureCreationInvoker invoker = + XMLSignatureCreationInvoker.getInstance(); + Element[] response = new Element[1]; + + // check that we have a CreateXMLSignatureRequest; if not, create an + // AxisFault, just like the org.apache.axis.providers.java.MsgProvider + if (request[0].getNodeName() != "CreateXMLSignatureRequest") { + QName qname = + new QName(request[0].getNamespaceURI(), request[0].getNodeName()); + throw new AxisFault( + Messages.getMessage("noOperationForQName", qname.toString())); + } + + // handle the request + try { + // create a parser and builder for binding API objects to/from XML + CreateXMLSignatureRequestParser requestParser = + new CreateXMLSignatureRequestParser(); + CreateXMLSignatureResponseBuilder responseBuilder = + new CreateXMLSignatureResponseBuilder(); + Element reparsedReq; + CreateXMLSignatureRequest requestObj; + CreateXMLSignatureResponse responseObj; + + // validate the request + reparsedReq = ServiceUtils.reparseRequest(request[0]); + + // convert to API objects + requestObj = requestParser.parse(reparsedReq); + + // invoke the core logic + responseObj = + invoker.createXMLSignature(requestObj, Collections.EMPTY_SET); + + // map back to XML + response[0] = responseBuilder.build(responseObj).getDocumentElement(); + + } catch (MOAException e) { + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } catch (Throwable t) { + MOASystemException e = new MOASystemException("2900", null, t); + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } + + return response; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java new file mode 100644 index 000000000..adb09ca0a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java @@ -0,0 +1,130 @@ +package at.gv.egovernment.moa.spss.server.service; + +import org.w3c.dom.Element; + +import org.apache.axis.AxisFault; + +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.MOASystemException; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.xmlbind.VerifyCMSSignatureRequestParser; +import at.gv.egovernment.moa.spss.api.xmlbind.VerifyCMSSignatureResponseBuilder; +import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureRequestParser; +import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker; +import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker; + +/** + * The service endpoint for the <code>SignatureVerification</code> web service. + * + * @author Patrick Peck + * @version $Id$ + */ +public class SignatureVerificationService { + + /** + * Handle a <code>VerifyCMSSignatureRequest</code>. + * + * @param request The <code>VerifyCMSSignatureRequest</code> to work on + * (contained in the 0th element of the array). + * @return A <code>VerifyCMSSignatureResponse</code> as the only element of + * the <code>Element</code> array. + * @throws AxisFault An error occurred during handling of the message. + */ + public Element[] VerifyCMSSignatureRequest(Element[] request) + throws AxisFault { + CMSSignatureVerificationInvoker invoker = + CMSSignatureVerificationInvoker.getInstance(); + Element[] response = new Element[1]; + + try { + // create a parser and builder for binding API objects to/from XML + VerifyCMSSignatureRequestParser requestParser = + new VerifyCMSSignatureRequestParser(); + VerifyCMSSignatureResponseBuilder responseBuilder = + new VerifyCMSSignatureResponseBuilder(); + Element reparsedReq; + VerifyCMSSignatureRequest requestObj; + VerifyCMSSignatureResponse responseObj; + + // validate the request + reparsedReq = ServiceUtils.reparseRequest(request[0]); + + // convert to API objects + requestObj = requestParser.parse(reparsedReq); + + // invoke the core logic + responseObj = invoker.verifyCMSSignature(requestObj); + + // map back to XML + response[0] = responseBuilder.build(responseObj).getDocumentElement(); + + } catch (MOAException e) { + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } catch (Throwable t) { + MOASystemException e = new MOASystemException("2900", null, t); + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } + + return response; + } + + /** + * Handle a <code>VerifyXMLSignatureRequest</code>. + * + * @param request The <code>VerifyXMLSignatureRequest</code> to work on + * (contained in the 0th element of the array). + * @return A <code>VerifyXMLSignatureResponse</code> as the only element of + * the <code>Element</code> array. + * @throws AxisFault An error occurred during handling of the message. + */ + public Element[] VerifyXMLSignatureRequest(Element[] request) + throws AxisFault { + XMLSignatureVerificationInvoker invoker = + XMLSignatureVerificationInvoker.getInstance(); + Element[] response = new Element[1]; + + try { + // create a parser and builder for binding API objects to/from XML + VerifyXMLSignatureRequestParser requestParser = + new VerifyXMLSignatureRequestParser(); + VerifyXMLSignatureResponseBuilder responseBuilder = + new VerifyXMLSignatureResponseBuilder(); + Element reparsedReq; + VerifyXMLSignatureRequest requestObj; + VerifyXMLSignatureResponse responseObj; + + // validate the request + reparsedReq = ServiceUtils.reparseRequest(request[0]); + + // convert to API objects + requestObj = requestParser.parse(reparsedReq); + + // invoke the core logic + responseObj = invoker.verifyXMLSignature(requestObj); + + // map back to XML + response[0] = responseBuilder.build(responseObj).getDocumentElement(); + + } catch (MOAException e) { + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } catch (Throwable t) { + MOASystemException e = new MOASystemException("2900", null, t); + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } + + return response; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/tools/CertTool.java b/spss.server/src/at/gv/egovernment/moa/spss/server/tools/CertTool.java new file mode 100644 index 000000000..9fe17eae2 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/tools/CertTool.java @@ -0,0 +1,242 @@ +package at.gv.egovernment.moa.spss.server.tools; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.security.cert.CertificateException; + +import iaik.asn1.structures.Name; +import iaik.pki.store.certstore.CertStoreException; +import iaik.pki.store.certstore.CertStoreTypes; +import iaik.pki.store.certstore.directory.DirectoryCertStore; +import iaik.pki.store.certstore.directory.DirectoryCertStoreParameters; +import iaik.pki.store.certstore.directory.DirectoryStoreException; +import iaik.security.ecc.provider.ECCProvider; +import iaik.security.provider.IAIK; +import iaik.utils.RFC2253NameParserException; +import iaik.x509.X509Certificate; + +/** + * A tool to support X509 certificate handling for configuring the MOA SP/SS + * service. + * + * This class provides functions for: + * <ul> + * <li>printing certificate information</li> + * <li>adding certificates to the cert store</li> + * </ul> + * + * @author Patrick Peck + * @version $Id$ + */ +public class CertTool { + + /** Error message if the DN cannot be parsed according to RFC2253. */ + private static final String ILLEGAL_RFC2253_NAME = + "Kein gültiger RFC2253-Name"; + + /** + * Main entry point of the tool. + * + * @param args The command line arguments. A single argument is expected, + * which is the file name of the X509 certificate to inspect. + */ + public static void main(String args[]) { + CertTool certTool = new CertTool(); + + if (args.length == 2 && "-info".equals(args[0])) { + initProviders(); + certTool.printCertInfo(args[1], System.out); + } else if (args.length == 3 && "-add".equals(args[0])) { + initProviders(); + certTool.addCertToCertStore(args[1], args[2]); + } else { + certTool.printUsage(System.err); + } + } + + /** + * Init the JCE providers, depending on the JDK used. + * + * Adds the IAIK JCE and IAIK ECC providers. + */ + private static void initProviders() { + if (System.getProperty("java.version").startsWith("1.3")) { + IAIK.addAsProvider(); + } else { + IAIK.addAsJDK14Provider(); + } + ECCProvider.addAsProvider(); + } + + /** + * Print the information about the certificate. + * + * This method will output information about the Subject DN, the Issuer DN and + * the serial number of the certificate. + * + * @param certFile The name of the certificate file to inspect. + * @param out The stream to print the information to. + */ + public void printCertInfo(String certFile, PrintStream out) { + try { + InputStream is = new BufferedInputStream(new FileInputStream(certFile)); + X509Certificate cert = new X509Certificate(is); + String issuerDN; + String serial; + String subjectDN; + + try { + subjectDN = ((Name) (cert.getSubjectDN())).getRFC2253String(); + } catch (RFC2253NameParserException e) { + subjectDN = ILLEGAL_RFC2253_NAME; + } + + try { + issuerDN = ((Name) (cert.getIssuerDN())).getRFC2253String(); + } catch (RFC2253NameParserException e) { + issuerDN = ILLEGAL_RFC2253_NAME; + } + + serial = cert.getSerialNumber().toString(); + + out.println("SubjectDN (RFC2253): " + subjectDN); + out.println("IssuerDN (RFC2253) : " + issuerDN); + out.println("Serial Number : " + serial); + } catch (FileNotFoundException e) { + System.err.println("Zertifikat nicht gefunden: " + certFile); + } catch (IOException e) { + System.err.println( + "I/O Fehler beim Lesen des Zertifikats: " + e.getMessage()); + } catch (CertificateException e) { + System.err.println( + "Fehler beim Lesen des Zertifikats: " + e.getMessage()); + } catch (Throwable t) { + System.err.println("Allgemeiner Fehler: " + t.getMessage()); + } + } + + /** + * Add a certificate to a directory certificate store. + * + * @param certFile The certificate to add. + * @param certStoreRoot The root directory of the certificate store. + */ + public void addCertToCertStore(String certFile, String certStoreRoot) { + try { + // read the certificate + InputStream is = new BufferedInputStream(new FileInputStream(certFile)); + X509Certificate cert = new X509Certificate(is); + + // initialize the DirectoryCertStore + DirectoryCertStore certStore = + new DirectoryCertStore( + new SimpleDirectoryCertStoreParameters(certStoreRoot), + null); + + certStore.storeCertificate(cert, null); + + System.out.println("\nDas Zertifikat wurde erfolreich hinzugefügt.\n"); + + } catch (FileNotFoundException e) { + System.err.println("Zertifikat nicht gefunden: " + certFile); + } catch (IOException e) { + System.err.println( + "I/O Fehler beim Lesen des Zertifikats: " + e.getMessage()); + } catch (CertificateException e) { + System.err.println( + "Fehler beim Lesen des Zertifikats: " + e.getMessage()); + } catch (DirectoryStoreException e) { + System.err.println( + "Fehler beim Öffnen des Zertifikatsspeichers: " + e.getMessage()); + } catch (CertStoreException e) { + System.err.println( + "Fehler beim Hinzufügen des Zertifikats: " + e.getMessage()); + } catch (Throwable t) { + System.err.println("Allgemeiner Fehler: " + t.getMessage()); + t.printStackTrace(); + } + } + + /** + * Print tool usage. + * + * @param out The <code>PrintStream</code> to print to. + */ + private void printUsage(PrintStream out) { + out.println("\nCerttool-Syntax:\n"); + out.println("-info <X509 Zertifikatsdatei"); + out.println(); + out.println("-add <X509 Zertifikatsdatei> <Zertifikatsspeicher>"); + out.println("\n"); + } + +} + +/** + * Simple implementation of the <code>DirectoryCertStoreParameters</code> + * interface intelligent enough for setting up a simple + * <code>DirectoryCertStore</code> in the <code>CertTool</code>. + * + * @author Patrick Peck + * @version $Id$ + */ +class SimpleDirectoryCertStoreParameters + implements DirectoryCertStoreParameters { + + /** The cert store root directory. */ + private String rootDirectory; + + /** + * Create a new <code>SimpleDirectoryCertStoreParameters</code> object. + * + * @param rootDirectory The root directory of the cert store. + */ + public SimpleDirectoryCertStoreParameters(String rootDirectory) { + this.rootDirectory = rootDirectory; + } + + /** + * @return <code>"MOA Directory CertStore"</code> + * @see iaik.pki.store.certstore.CertStoreParameters#getId() + */ + public String getId() { + return "MOA Directory CertStore"; + } + + /** + * @return CertStoreTypes.DIRECTORY + * @see iaik.pki.store.certstore.CertStoreParameters#getType() + */ + public String getType() { + return CertStoreTypes.DIRECTORY; + } + + /** + * @return <code>false</code> + * @see iaik.pki.store.certstore.CertStoreParameters#isReadOnly() + */ + public boolean isReadOnly() { + return false; + } + + /** + * @return <code>false</code> + * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#createNew() + */ + public boolean createNew() { + return false; + } + + /** + * @return The root directory given at construction time. + * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#getRootDirectory() + */ + public String getRootDirectory() { + return rootDirectory; + } + +}
\ No newline at end of file diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java new file mode 100644 index 000000000..407dbd4e9 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java @@ -0,0 +1,90 @@ +package at.gv.egovernment.moa.spss.server.transaction; + +import java.security.cert.X509Certificate; + +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; + +/** + * Contains information about the current request. + * + * @author Stefan Knirsch + * @author Patrick Peck + */ +public class TransactionContext { + + /** The client certificate. */ + private X509Certificate[] clientCertificate = null; + /** The transaction ID. */ + private String transactionID = null; + /** The name of the request. */ + private String requestName = null; + /** The configuration to use throughout the request. */ + private ConfigurationProvider configuration = null; + + /** + * Create a <code>TransactionContext</code> object. + * + * @param transactionID A unique ID for this <code>TransactionContext</code>. + * @param clientCertificate The client certificate chain. + * @param configuration The MOA configuration to use for this transaction. + */ + public TransactionContext( + String transactionID, + X509Certificate[] clientCertificate, + ConfigurationProvider configuration) { + + this.transactionID = transactionID; + this.clientCertificate = clientCertificate; + this.configuration = configuration; + } + + /** + * Returns the client certificate. + * + * @return The client certificate chain, if SSL client authentication has been + * configured in the web server and has been used by the client. The 0th + * element of the array contains the client certificate. <code>null</code> + * otherwise. + */ + public X509Certificate[] getClientCertificate() { + return clientCertificate; + } + + /** + * Returns the unique transaction ID. + * + * @return The transaction ID. + */ + public String getTransactionID() { + return transactionID; + } + + /** + * Returns the name of the request. + * + * @return The name of the request. + */ + public String getRequestName() { + return requestName; + } + + /** + * Sets the name of the request. + * + * @param requestName The request name to set. + */ + public void setRequestName(String requestName) { + this.requestName = requestName; + } + + /** + * Returns the <code>ConfigurationProvider</code> associated with this + * transaction. + * + * @return The ConfigurationProvider associated with this transaction. + */ + public ConfigurationProvider getConfiguration() { + return configuration; + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContextManager.java b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContextManager.java new file mode 100644 index 000000000..13127c3ae --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContextManager.java @@ -0,0 +1,62 @@ +package at.gv.egovernment.moa.spss.server.transaction; + +/** + * Provides each thread with an instance of <code>TransactionContext</code>. + * + * The single instance of the <code>TransactionContextManager</code> should be + * used to access contextual information for each web service transaction, e.g. + * the transaction ID, MOA configuration, client certificate, etc. + * + * @author Stefan Knirsch + * @author Patrick Peck + */ +public class TransactionContextManager { + + /** The single instance of <code>TransactionContextManager</code> */ + private static TransactionContextManager instance = null; + + /** Contains a single <code>TransactionContext</code> for each thread. */ + private ThreadLocal context = null; + + /** + * Get the single instance of <code>TransactionContextManager</code>. + * + * @return The single instanc of <code>TransactionContextManager</code>. + */ + public static synchronized TransactionContextManager getInstance() { + if (instance == null) { + instance = new TransactionContextManager(); + } + return instance; + } + + /** + * Creates a new <code>TransactionContextManager</code>. + * + * Protected to disallow direct instantiation. + */ + protected TransactionContextManager() { + context = new ThreadLocal(); + } + + /** + * Set the <code>TransactionContext</code> for the current thread. + * + * @param txContext The <code>TransactionContext</code> for this thread. + */ + public void setTransactionContext(TransactionContext txContext) { + context.set(txContext); + } + + /** + * Get the <code>TransactionContext</code> for the current thread. + * + * @return The <code>TransactionContext</code> for the current thread or + * <code>null</code>, if none has been set (or if this method is being invoked + * outside the bounds of a transaction). + */ + public TransactionContext getTransactionContext() { + return (TransactionContext) context.get(); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionIDGenerator.java b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionIDGenerator.java new file mode 100644 index 000000000..6eb07defe --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionIDGenerator.java @@ -0,0 +1,51 @@ +package at.gv.egovernment.moa.spss.server.transaction; + + +/** + * A generator for unique transaction IDs. + * + * <p>The transaction IDs are of the form "<base>-<counter>", where: + * <ul> + * <li><code>base</code> is initialized with the system time when this class is + * being loaded</li> + * <li><code>counter</code> is incremented sequentially on each call to + * <code>nextID()</code></li> + * </ul> + * </p> + * + * <p> Assuming that it is highly unlikely that MOA servers are started at + * exactly the same time instant, the mechanism provided by this class should + * guarantee unique transaction IDs across multiple restarts and/or instances of + * the server.</p> + * + * @author Patrick Peck + * @author Stefan Knirsch + */ +public class TransactionIDGenerator { + + /** Request sequence number. */ + private static long counter = 0; + /** The base value to which to append the sequence number. */ + private static String base = null; + + /** + * Set up the initial base value. + */ + static { + synchronized (TransactionIDGenerator.class) { + base = Long.toString(System.currentTimeMillis()); + } + } + + /** + * Returns the next transaction ID. + * + * @return The next transaction ID. + */ + public static synchronized String nextID() { + counter++; + + return (base + "-" + counter); + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/util/IdGenerator.java b/spss.server/src/at/gv/egovernment/moa/spss/server/util/IdGenerator.java new file mode 100644 index 000000000..92e8cb0f8 --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/util/IdGenerator.java @@ -0,0 +1,61 @@ +package at.gv.egovernment.moa.spss.server.util; + +import java.util.Set; + +/** + * Generate unique ID values for various objects in the response. + * + * @author Patrick Peck + * @version $Id$ + */ +public class IdGenerator { + /** The base value to append the counter to. */ + private String base; + /** The <code>Set</code> of reserved ID values. */ + private Set reserved; + /** The sequence number. */ + private int count; + + /** + * Create a new <code>IdGenerator</code>. + * + * @param base A base value to append the IDs to. The creator of this object + * should provide a base value, so that appending the counter leads to unique + * IDs. + * @param reserved The <code>Set</code> of reserved IDs. A call to + * <code>uniqueId()</code> will respect the reserved IDs. + */ + public IdGenerator(String base, Set reserved) { + this.base = base; + this.reserved = reserved; + count = 1; + } + + /** + * Create the next ID value in the sequence. + * + * @return The next ID value in the sequence. + */ + public String nextId() { + return base + "-" + count++; + } + + /** + * Create the next unique ID value which is unique in the reserved ID set. + * + * The created ID is added to the set of reserved IDs. + * + * @return The next ID value. + */ + public String uniqueId() { + String nextId; + + while (reserved.contains(nextId = nextId())); + + reserved.add(nextId); + + return nextId; + + } + +} diff --git a/spss.server/src/at/gv/egovernment/moa/spss/util/MessageProvider.java b/spss.server/src/at/gv/egovernment/moa/spss/util/MessageProvider.java new file mode 100644 index 000000000..a6f6c1d4a --- /dev/null +++ b/spss.server/src/at/gv/egovernment/moa/spss/util/MessageProvider.java @@ -0,0 +1,65 @@ +package at.gv.egovernment.moa.spss.util; + +import java.util.Locale; + +import at.gv.egovernment.moa.util.Messages; + +/** + * Singleton wrapper around a <code>Messages</code> object. + * + * @author Patrick Peck + * @version $Id$ + */ +public class MessageProvider { + + /** The resource names of the messages to load. */ + private static final String[] DEFAULT_MESSAGE_RESOURCES = + { "resources/properties/spss_messages" }; + /** The corresponding message locales. */ + private static final Locale[] DEFAULT_MESSAGE_LOCALES = + new Locale[] { new Locale("de", "AT") }; + /** The single instance of this class. */ + private static MessageProvider instance; + + /** The messages provided by the <code>MessageProvider</code>. */ + private Messages messages; + + /** + * Return the single instance of the <code>MessageProvider</code>. + * + * Intialilizes the <code>MessageProvider</code> with the default message + * locations: <code>/resources/properties/spss_messages</code>. + * + * @return The single <code>MessageProvider</code>. + */ + public static synchronized MessageProvider getInstance() { + if (instance == null) { + instance = + new MessageProvider(DEFAULT_MESSAGE_RESOURCES, DEFAULT_MESSAGE_LOCALES); + } + return instance; + } + + /** + * Create a <code>MessageProvider</code>. + * + * @param resourceNames The names of the resources containing the messages. + * @param locales The corresponding locales. + */ + protected MessageProvider(String[] resourceNames, Locale[] locales) { + this.messages = new Messages(resourceNames, locales); + } + + /** + * Get the message corresponding to a given message ID. + * + * @param messageId The ID of the message. + * @param parameters The parameters to fill in into the message arguments. + * @return The formatted message. + */ + public String getMessage(String messageId, Object[] parameters) { + return messages.getMessage(messageId, parameters); + } + + +} |