aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/AxisSecureSocketFactory.java212
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAConstants.java36
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java572
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPRequestJSPForwarder.java76
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java68
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java374
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/MOAIDMessageProvider.java58
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java62
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java22
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java180
10 files changed, 1660 insertions, 0 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/AxisSecureSocketFactory.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/AxisSecureSocketFactory.java
new file mode 100644
index 000000000..954a87e62
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/AxisSecureSocketFactory.java
@@ -0,0 +1,212 @@
+package at.gv.egovernment.moa.id.util;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.util.Hashtable;
+
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.axis.components.net.BooleanHolder;
+import org.apache.axis.components.net.DefaultSocketFactory;
+import org.apache.axis.components.net.SecureSocketFactory;
+import org.apache.axis.components.net.TransportClientProperties;
+import org.apache.axis.components.net.TransportClientPropertiesFactory;
+import org.apache.axis.utils.Messages;
+import org.apache.axis.utils.XMLUtils;
+
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * Secure socket factory for Axis webs service clients of the MOA-ID component,
+ * which are the MOA-SP calls from MOA-ID Auth,
+ * and the MOA-ID Auth calls from MOA-ID Proxy.
+ * <br/>Use this initialization code:<br/>
+ * <code> // ConnectionParameter connParam = ... get from ConfigurationProvider
+ * AxisSecureSocketFactory.initialize(connParam);</code>
+ * <br/>See the Apache Axis documentation on how to configure this class
+ * as the default secure socket factory to be used by Axis.
+ * <br/>
+ * This code has been copied from <code>JSSESocketFactory</code>, the
+ * method <code>initialize()</code> has been added.
+ *
+ *
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class AxisSecureSocketFactory
+ extends DefaultSocketFactory implements SecureSocketFactory {
+
+ /** Field sslFactory */
+ private static SSLSocketFactory sslFactory;
+
+ /**
+ * Constructor for AxisSecureSocketFactory.
+ * @param attributes ???
+ */
+ public AxisSecureSocketFactory(Hashtable attributes) {
+ super(attributes);
+ }
+ /**
+ * Initializes the factory by setting the connection parameters to be used for
+ * setting the secure socket factory, and by setting the system property
+ * <code>axis.socketSecureFactory</code>.
+ * @param ssf <code>SSLSocketFactory</code> to initialize with
+ */
+ public static void initialize(SSLSocketFactory ssf)
+ throws IOException, GeneralSecurityException {
+
+ Logger.debug("Initialize AxisSecureSocketFactory");
+ sslFactory = ssf;
+ }
+
+ /**
+ * creates a secure socket
+ *
+ * @param host
+ * @param port
+ * @param otherHeaders
+ * @param useFullURL
+ *
+ * @return Socket
+ * @throws Exception
+ */
+ public Socket create(
+ String host,
+ int port,
+ StringBuffer otherHeaders,
+ BooleanHolder useFullURL)
+ throws Exception {
+ if (port == -1) {
+ port = 443;
+ }
+
+ TransportClientProperties tcp =
+ TransportClientPropertiesFactory.create("https");
+
+ boolean hostInNonProxyList =
+ isHostInNonProxyList(host, tcp.getNonProxyHosts());
+
+ Socket sslSocket = null;
+ if (tcp.getProxyHost().length() == 0 || hostInNonProxyList) {
+ // direct SSL connection
+ sslSocket = sslFactory.createSocket(host, port);
+ }
+ else {
+
+ // Default proxy port is 80, even for https
+ int tunnelPort =
+ (tcp.getProxyPort().length() != 0)
+ ? Integer.parseInt(tcp.getProxyPort())
+ : 80;
+ if (tunnelPort < 0)
+ tunnelPort = 80;
+
+ // Create the regular socket connection to the proxy
+ Socket tunnel = new Socket(tcp.getProxyHost(), tunnelPort);
+
+ // The tunnel handshake method (condensed and made reflexive)
+ OutputStream tunnelOutputStream = tunnel.getOutputStream();
+ PrintWriter out =
+ new PrintWriter(
+ new BufferedWriter(new OutputStreamWriter(tunnelOutputStream)));
+
+ // More secure version... engage later?
+ // PasswordAuthentication pa =
+ // Authenticator.requestPasswordAuthentication(
+ // InetAddress.getByName(tunnelHost),
+ // tunnelPort, "SOCK", "Proxy","HTTP");
+ // if(pa == null){
+ // printDebug("No Authenticator set.");
+ // }else{
+ // printDebug("Using Authenticator.");
+ // tunnelUser = pa.getUserName();
+ // tunnelPassword = new String(pa.getPassword());
+ // }
+ out.print(
+ "CONNECT "
+ + host
+ + ":"
+ + port
+ + " HTTP/1.0\r\n"
+ + "User-Agent: AxisClient");
+ if (tcp.getProxyUser().length() != 0
+ && tcp.getProxyPassword().length() != 0) {
+
+ // add basic authentication header for the proxy
+ String encodedPassword =
+ XMLUtils.base64encode(
+ (tcp.getProxyUser() + ":" + tcp.getProxyPassword()).getBytes());
+
+ out.print("\nProxy-Authorization: Basic " + encodedPassword);
+ }
+ out.print("\nContent-Length: 0");
+ out.print("\nPragma: no-cache");
+ out.print("\r\n\r\n");
+ out.flush();
+ InputStream tunnelInputStream = tunnel.getInputStream();
+
+ if (log.isDebugEnabled()) {
+ log.debug(
+ Messages.getMessage(
+ "isNull00",
+ "tunnelInputStream",
+ "" + (tunnelInputStream == null)));
+ }
+ String replyStr = "";
+
+ // Make sure to read all the response from the proxy to prevent SSL negotiation failure
+ // Response message terminated by two sequential newlines
+ int newlinesSeen = 0;
+ boolean headerDone = false; /* Done on first newline */
+
+ while (newlinesSeen < 2) {
+ int i = tunnelInputStream.read();
+
+ if (i < 0) {
+ throw new IOException("Unexpected EOF from proxy");
+ }
+ if (i == '\n') {
+ headerDone = true;
+ ++newlinesSeen;
+ }
+ else if (i != '\r') {
+ newlinesSeen = 0;
+ if (!headerDone) {
+ replyStr += String.valueOf((char) i);
+ }
+ }
+ }
+ if (!replyStr.startsWith("HTTP/1.0 200")
+ && !replyStr.startsWith("HTTP/1.1 200")) {
+ throw new IOException(
+ Messages.getMessage(
+ "cantTunnel00",
+ new String[] { tcp.getProxyHost(), "" + tunnelPort, replyStr }));
+ }
+
+ // End of condensed reflective tunnel handshake method
+ sslSocket = sslFactory.createSocket(tunnel, host, port, true);
+ if (log.isDebugEnabled()) {
+ log.debug(
+ Messages.getMessage(
+ "setupTunnel00",
+ tcp.getProxyHost(),
+ "" + tunnelPort));
+ }
+ }
+
+ ((SSLSocket) sslSocket).startHandshake();
+ if (log.isDebugEnabled()) {
+ log.debug(Messages.getMessage("createdSSL00"));
+ }
+ return sslSocket;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAConstants.java
new file mode 100644
index 000000000..c5dad8bc4
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAConstants.java
@@ -0,0 +1,36 @@
+/*
+ * Created on 20.01.2005
+ *
+ * @author rschamberger
+ * $ID$
+ */
+package at.gv.egovernment.moa.id.util;
+
+
+/**
+ * Class used to define Constants used in Class ECDSAKeyValueConverter
+ *
+ * * @author rschamberger
+ */
+public class ECDSAConstants {
+
+ /* ECDSA Namespace
+ */
+ static String NAMESPACE_ECDSAKEYVALUE_ = "http://www.w3.org/2001/04/xmldsig-more#";
+
+ /* Schema instance NS
+ */
+ static String NAMESPACE_XSI_ = "http://www.w3.org/2001/XMLSchema-instance";
+
+ /* ecdsa prefix value
+ */
+ static String NS_PREFIX_ECDSAKEYVALUE_ = "ecdsa";
+
+ /* namespace namespace
+ */
+ static String NAMESPACE_NAMESPACES_ = "http://www.w3.org/XML/1998/namespace";
+
+ /* si prefix value
+ */
+ static String NS_PREFIX_XSI_ = "si";
+};
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java
new file mode 100644
index 000000000..6fb78edb7
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java
@@ -0,0 +1,572 @@
+package at.gv.egovernment.moa.id.util;
+
+import iaik.security.ecc.ecdsa.ECDSAParameter;
+import iaik.security.ecc.ecdsa.ECPublicKey;
+import iaik.security.ecc.math.ecgroup.AffineCoordinate;
+import iaik.security.ecc.math.ecgroup.Coordinate;
+import iaik.security.ecc.math.ecgroup.CoordinateTypes;
+import iaik.security.ecc.math.ecgroup.ECGroupFactory;
+import iaik.security.ecc.math.ecgroup.ECPoint;
+import iaik.security.ecc.math.ecgroup.EllipticCurve;
+import iaik.security.ecc.math.field.Field;
+import iaik.security.ecc.math.field.FieldElement;
+import iaik.security.ecc.math.field.PrimeField;
+import iaik.security.ecc.parameter.ECCParameterFactory;
+import iaik.security.ecc.spec.ECCParameterSpec;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class ECDSAKeyValueConverter
+{
+
+
+ //TODO enhance javadoc
+
+ /**
+ * converter class which can be used to convert ECDSA keys encoded in XML
+ * to a PublicKey data structure
+ * @param keyValueElem ECDSAKeyValue Element
+ * @return ECPublicKey encoded in PublicKey data structure
+ * @throws Exception
+ */
+ public static PublicKey element2ECDSAPublicKey(Element keyValueElem) throws Exception
+ {
+ String ecdsaNS = ECDSAConstants.NAMESPACE_ECDSAKEYVALUE_;
+
+ // Domain parameters
+ Element domainParams = getChildElement(keyValueElem, ecdsaNS, "DomainParameters", 1);
+ if (domainParams == null) throw new Exception("Domain parameters must not be implicit.");
+
+ Element namedCurve = getChildElement(domainParams, ecdsaNS, "NamedCurve", 1);
+ ECCParameterSpec eccParameterSpec;
+
+ if (namedCurve != null)
+ {
+ // URL curveNameURN = new URL(namedCurve.getAttributeNS(null, "URN"));
+ String curveNameOID = namedCurve.getAttributeNS(null, "URN").substring(8);
+ ECCParameterFactory eccParamFactory = ECCParameterFactory.getInstance();
+ // eccParameterSpec = eccParamFactory.getParameterByOID(curveNameURN.getPath().substring(4));
+ eccParameterSpec = eccParamFactory.getParameterByOID(curveNameOID);
+ }
+ else
+ {
+ Element excplicitParams = getChildElement(domainParams, ecdsaNS, "ExplicitParams", 1);
+ Element fieldParams = getChildElement(excplicitParams, ecdsaNS, "FieldParams", 1);
+ Element curveParams = getChildElement(excplicitParams, ecdsaNS, "CurveParams", 1);
+ Element basePointParams = getChildElement(excplicitParams, ecdsaNS, "BasePointParams", 1);
+
+ // Field parameters
+ String fieldParamsTypeStr = fieldParams.getAttributeNS(ECDSAConstants.NAMESPACE_XSI_, "type");
+ String ecdsaNSPrefix = getECDSANSPrefix(fieldParams);
+ BigInteger p = null;
+ int fieldParamsType = 0;
+ final int FIELD_TYPE_PRIME = 1;
+ final int FIELD_TYPE_TNB = 2;
+ final int FIELD_TYPE_PNB = 3;
+ int m = -1, k = -1, k1 = -1, k2 = -1, k3 = -1;
+ if (fieldParamsTypeStr.equals(ecdsaNSPrefix + ":PrimeFieldParamsType"))
+ {
+ fieldParamsType = FIELD_TYPE_PRIME;
+ String pStr = getChildElementText(fieldParams, ecdsaNS, "P", 1);
+ p = new BigInteger(pStr, 10);
+ }
+ else if (fieldParamsTypeStr.equals(ecdsaNSPrefix + ":TnBFieldParamsType"))
+ {
+ fieldParamsType = FIELD_TYPE_TNB;
+ String mStr = getChildElementText(fieldParams, ecdsaNS, "M", 1);
+ m = Integer.parseInt(mStr);
+ String kStr = getChildElementText(fieldParams, ecdsaNS, "K", 1);
+ k = Integer.parseInt(kStr);
+ }
+ else if (fieldParamsTypeStr.equals(ecdsaNSPrefix + ":PnBFieldParamsType"))
+ {
+ fieldParamsType = FIELD_TYPE_PNB;
+ String mStr = getChildElementText(fieldParams, ecdsaNS, "M", 1);
+ m = Integer.parseInt(mStr);
+ String k1Str = getChildElementText(fieldParams, ecdsaNS, "K1", 1);
+ k1 = Integer.parseInt(k1Str);
+ String k2Str = getChildElementText(fieldParams, ecdsaNS, "K2", 1);
+ k2 = Integer.parseInt(k2Str);
+ String k3Str = getChildElementText(fieldParams, ecdsaNS, "K3", 1);
+ k3 = Integer.parseInt(k3Str);
+ }
+ else throw new Exception("Unknown field parameters.");
+
+ // Curve parameters
+ Element aElem = getChildElement(curveParams, ecdsaNS, "A", 1);
+ String aStr = aElem.getAttributeNS(null, "Value");
+ Element bElem = getChildElement(curveParams, ecdsaNS, "B", 1);
+ String bStr = bElem.getAttributeNS(null, "Value");
+ String seedStr = getChildElementText(curveParams, ecdsaNS, "Seed", 1);
+ BigInteger seed = (seedStr != null) ? new BigInteger(seedStr, 10) : null;
+
+ // Base point parameters
+ Element basePoint = getChildElement(basePointParams, ecdsaNS, "BasePoint", 1);
+ Element basePointXElem = getChildElement(basePoint, ecdsaNS, "X", 1);
+ String basePointXStr = basePointXElem.getAttributeNS(null, "Value");
+ Element basePointYElem = getChildElement(basePoint, ecdsaNS, "Y", 1);
+ String basePointYStr = basePointYElem.getAttributeNS(null, "Value");
+ String orderStr = getChildElementText(basePointParams, ecdsaNS, "Order", 1);
+ BigInteger order = new BigInteger(orderStr, 10);
+ String cofactorStr = getChildElementText(basePointParams, ecdsaNS, "Cofactor", 1);
+ BigInteger cofactor = (cofactorStr != null) ? new BigInteger(cofactorStr, 10) : null;
+
+ if (fieldParamsType == FIELD_TYPE_PRIME)
+ {
+ BigInteger a = new BigInteger(aStr, 10);
+ BigInteger b = new BigInteger(bStr, 10);
+ BigInteger basePointX = new BigInteger(basePointXStr, 10);
+ BigInteger basePointY = new BigInteger(basePointYStr, 10);
+ eccParameterSpec = new ECCParameterSpec(p, cofactor, order, seed, null, a, b, basePointX,
+ basePointY, null);
+ }
+ else
+ {
+ int[] irreducible = new int[m/32 + ((m % 32 != 0) ? 1 : 0)];
+ if (fieldParamsType == FIELD_TYPE_TNB)
+ {
+ irreducible[m/32] = 1 << m % 32;
+ irreducible[k/32] += 1 << k % 32;
+ irreducible[0] += 1;
+ }
+ else
+ {
+ irreducible[m/32] = 1 << m % 32;
+ irreducible[k3/32] += 1 << k3 % 32;
+ irreducible[k2/32] += 1 << k2 % 32;
+ irreducible[k1/32] += 1 << k1 % 32;
+ irreducible[0] += 1;
+ }
+ eccParameterSpec = new ECCParameterSpec(irreducible, cofactor, order, octetString2IntArray(aStr),
+ octetString2IntArray(bStr), octetString2IntArray(basePointXStr),
+ octetString2IntArray(basePointYStr), null);
+ }
+ }
+
+ // Public key
+ Element publicKeyElem = getChildElement(keyValueElem, ecdsaNS, "PublicKey", 1);
+ Element publicKeyXElem = getChildElement(publicKeyElem, ecdsaNS, "X", 1);
+ String publicKeyXStr = publicKeyXElem.getAttributeNS(null, "Value");
+ Element publicKeyYElem = getChildElement(publicKeyElem, ecdsaNS, "Y", 1);
+ String publicKeyYStr = publicKeyYElem.getAttributeNS(null, "Value");
+
+ ECDSAParameter ecdsaParams = new ECDSAParameter(eccParameterSpec, CoordinateTypes.PROJECTIVE_COORDINATES);
+ ECGroupFactory ecGroupFactory = ECGroupFactory.getInstance();
+ EllipticCurve eCurve = ecGroupFactory.getCurve(eccParameterSpec.getA(),
+ eccParameterSpec.getB(), eccParameterSpec.getR(), CoordinateTypes.PROJECTIVE_COORDINATES);
+ Field field = eCurve.getField();
+
+ // Detect type of public key field elements
+ String elementType = publicKeyXElem.getAttributeNS(ECDSAConstants.NAMESPACE_XSI_, "type");
+ String elementTypeLocalName = elementType.substring(elementType.indexOf(':') + 1);
+ int FIELD_TYPE_PRIME = 1, FIELD_TYPE_CHAR_TWO = 2;
+ int fieldElemType = ("PrimeFieldElemType".equals(elementTypeLocalName))
+ ? FIELD_TYPE_PRIME
+ : FIELD_TYPE_CHAR_TWO;
+
+ FieldElement publicKeyPointX, publicKeyPointY;
+ if (fieldElemType == FIELD_TYPE_PRIME)
+ {
+
+// Value xValue = FieldFactory.getInstance().getPrimeFieldValue(new BigInteger(publicKeyXStr, 10));
+// publicKeyPointX = field.newElement(xValue);
+ PrimeField pf = (PrimeField) field;
+ publicKeyPointX = pf.newElement(new BigInteger(publicKeyXStr, 10));
+// Value yValue = FieldFactory.getInstance().getPrimeFieldValue(new BigInteger(publicKeyYStr, 10));
+// publicKeyPointY = field.newElement(yValue);
+ publicKeyPointY = pf.newElement(new BigInteger(publicKeyYStr, 10));
+ }
+ else
+ {
+ publicKeyPointX = field.newElement(octetString2ByteArray(publicKeyXStr));
+ publicKeyPointY = field.newElement(octetString2ByteArray(publicKeyYStr));
+ }
+// ProjectiveCoordinate publicKeyPointCoordinate = new ProjectiveCoordinate(publicKeyPointX,
+// publicKeyPointY, field.getONEelement());
+ Coordinate publicKeyPointCoordinate = new AffineCoordinate(publicKeyPointX,
+ publicKeyPointY).toProjective();
+ ECPoint publicKeyPoint = eCurve.newPoint(publicKeyPointCoordinate);
+ ECPublicKey publicKey = new ECPublicKey(ecdsaParams, publicKeyPoint);
+
+ return publicKey;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /*
+ public static Element publicKey2ECDSAKeyValueElement(boolean implParams, String curveOID,
+ ECDSAPublicKey publicKey, Document factoryDoc)
+ {
+ String ecdsaNS = ECDSAConstants.NAMESPACE_ECDSAKEYVALUE_;
+ String ecdsaNSP = ECDSAConstants.NS_PREFIX_ECDSAKEYVALUE_;
+ String nsNS = ECDSAConstants.NAMESPACE_NAMESPACES_;
+ String xsiNS = ECDSAConstants.NAMESPACE_XSI_;
+ String xsiNSP = ECDSAConstants.NS_PREFIX_XSI_;
+
+ ECDSAParameter params = (ECDSAParameter)publicKey.getParameter();
+ EllipticCurve curve = params.getG().getCurve();
+ Field field = curve.getField();
+ int fieldId = curve.getField().getFieldId();
+
+ Element eCDSAKeyValue = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":ECDSAKeyValue");
+ eCDSAKeyValue.setAttributeNS(nsNS, "xmlns:" + ecdsaNSP, ecdsaNS);
+ eCDSAKeyValue.setAttributeNS(nsNS, "xmlns:" + xsiNSP, xsiNS);
+
+ // Detect field type
+ int coeffPositions[] = new int[3];
+ int fieldType = 0;
+ String fieldElemTypeString = null;
+ final int FT_PRIME = 1, FT_TNB = 2, FT_PNB = 3;
+ if (fieldId == Field.PRIME_FIELD)
+ {
+ fieldType = FT_PRIME;
+ fieldElemTypeString = ecdsaNSP + ":PrimeFieldElemType";
+ }
+ else
+ {
+ // Get irreducible polynomal
+ BinaryField binaryField = (BinaryField)field;
+ BinaryFieldValue irreducible = binaryField.getIrreducible();
+
+ // Get coefficients of irreducible polynomal
+ int order = irreducible.getOrder();
+ int coeffCount = 2;
+ for (int i = 1; i < order - 1; i++)
+ {
+ if (irreducible.testBit(i))
+ {
+ coeffPositions[coeffCount - 2] = i;
+ coeffCount++;
+ if (coeffCount == 5) break;
+ }
+ }
+
+ // Set polynomal type (TNB or
+ fieldType = (coeffCount == 3) ? FT_TNB : FT_PNB;
+ fieldElemTypeString = ecdsaNSP + ":CharTwoFieldElemType";
+ }
+
+ if (!implParams)
+ {
+ Element domainParameters = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":DomainParameters");
+ eCDSAKeyValue.appendChild(factoryDoc.createTextNode("\n "));
+ eCDSAKeyValue.appendChild(domainParameters);
+
+ if (curveOID != null)
+ {
+ // Named curve
+ Element namedCurve = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":NamedCurve");
+ namedCurve.setAttributeNS(null, "URN", "urn:oid:" + curveOID);
+ domainParameters.appendChild(factoryDoc.createTextNode("\n "));
+ domainParameters.appendChild(namedCurve);
+ domainParameters.appendChild(factoryDoc.createTextNode("\n "));
+ }
+ else
+ {
+ // Explicit parameters
+ Element explicitParams = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":ExplicitParams");
+
+ // Field parameters
+ Element fieldParams = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":FieldParams");
+ explicitParams.appendChild(factoryDoc.createTextNode("\n "));
+ explicitParams.appendChild(fieldParams);
+
+ if (fieldType == FT_PRIME)
+ {
+ fieldParams.setAttributeNS(xsiNS, xsiNSP + ":type", ecdsaNSP + ":PrimeFieldParamsType");
+ Element p = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":P");
+ p.appendChild(factoryDoc.createTextNode(curve.getField().getSize().toString(10)));
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ fieldParams.appendChild(p);
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ }
+ else if (fieldType == FT_TNB)
+ {
+ fieldParams.setAttributeNS(xsiNS, xsiNSP + ":type", ecdsaNSP + ":TnBFieldParamsType");
+ Element m = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":M");
+ m.appendChild(factoryDoc.createTextNode(Integer.toString(curve.getField().getOrder())));
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ fieldParams.appendChild(m);
+
+ Element k = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":K");
+ k.appendChild(factoryDoc.createTextNode(Integer.toString(coeffPositions[0], 10)));
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ fieldParams.appendChild(k);
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ }
+ else
+ {
+ fieldParams.setAttributeNS(xsiNS, xsiNSP + ":type", ecdsaNSP + ":PnBFieldParamsType");
+ Element m = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":M");
+ m.appendChild(factoryDoc.createTextNode(Integer.toString(curve.getField().getOrder())));
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ fieldParams.appendChild(m);
+
+ Element k1 = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":K1");
+ k1.appendChild(factoryDoc.createTextNode(Integer.toString(coeffPositions[0])));
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ fieldParams.appendChild(k1);
+
+ Element k2 = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":K2");
+ k2.appendChild(factoryDoc.createTextNode(Integer.toString(coeffPositions[1])));
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ fieldParams.appendChild(k2);
+
+ Element k3 = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":K3");
+ k3.appendChild(factoryDoc.createTextNode(Integer.toString(coeffPositions[2])));
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ fieldParams.appendChild(k3);
+ fieldParams.appendChild(factoryDoc.createTextNode("\n "));
+ }
+
+ // Curve parameters
+ Element curveParams = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":CurveParams");
+ explicitParams.appendChild(factoryDoc.createTextNode("\n "));
+ explicitParams.appendChild(curveParams);
+
+ Element a = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":A");
+ a.setAttributeNS(xsiNS, xsiNSP + ":type", fieldElemTypeString);
+ a.setAttributeNS(null, "Value",
+ (fieldId == Field.PRIME_FIELD)
+ ? curve.getA().getValue().toBigInt().toString(10)
+ : evenStringLength(curve.getA().getValue().toBigInt().toString(16)));
+ curveParams.appendChild(factoryDoc.createTextNode("\n "));
+ curveParams.appendChild(a);
+
+ Element b = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":B");
+ b.setAttributeNS(xsiNS, xsiNSP + ":type", fieldElemTypeString);
+ b.setAttributeNS(null, "Value",
+ (fieldId == Field.PRIME_FIELD)
+ ? curve.getB().getValue().toBigInt().toString(10)
+ : evenStringLength(curve.getB().getValue().toBigInt().toString(16)));
+ curveParams.appendChild(factoryDoc.createTextNode("\n "));
+ curveParams.appendChild(b);
+
+ if (params.getS() != null)
+ {
+ Element seed = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":Seed");
+ seed.appendChild(factoryDoc.createTextNode(evenStringLength(params.getS().toString(16))));
+ curveParams.appendChild(factoryDoc.createTextNode("\n "));
+ curveParams.appendChild(seed);
+ }
+
+ curveParams.appendChild(factoryDoc.createTextNode("\n "));
+
+ // Base point params
+ Element basePointParams = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":BasePointParams");
+ explicitParams.appendChild(factoryDoc.createTextNode("\n "));
+ explicitParams.appendChild(basePointParams);
+
+ Element basePoint = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":BasePoint");
+ basePointParams.appendChild(factoryDoc.createTextNode("\n "));
+ basePointParams.appendChild(basePoint);
+
+ Element x = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":X");
+ x.setAttributeNS(xsiNS, xsiNSP + ":type", fieldElemTypeString);
+ x.setAttributeNS(null, "Value",
+ (fieldId == Field.PRIME_FIELD)
+ ? params.getG().getCoordinates().getX().getValue().toBigInt().toString(10)
+ : evenStringLength(params.getG().getCoordinates().getX().getValue().toBigInt().toString(16)));
+ basePoint.appendChild(factoryDoc.createTextNode("\n "));
+ basePoint.appendChild(x);
+
+ Element y = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":Y");
+ y.setAttributeNS(xsiNS, xsiNSP + ":type", fieldElemTypeString);
+ y.setAttributeNS(null, "Value",
+ (fieldId == Field.PRIME_FIELD)
+ ? params.getG().getCoordinates().getY().getValue().toBigInt().toString(10)
+ : evenStringLength(params.getG().getCoordinates().getY().getValue().toBigInt().toString(16)));
+ basePoint.appendChild(factoryDoc.createTextNode("\n "));
+ basePoint.appendChild(y);
+ basePoint.appendChild(factoryDoc.createTextNode("\n "));
+
+ Element order = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":Order");
+ order.appendChild(factoryDoc.createTextNode(params.getR().toString(10)));
+ basePointParams.appendChild(factoryDoc.createTextNode("\n "));
+ basePointParams.appendChild(order);
+
+ if (params.getK() != null)
+ {
+ Element cofactor = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":Cofactor");
+ cofactor.appendChild(factoryDoc.createTextNode(params.getK().toString(10)));
+ basePointParams.appendChild(factoryDoc.createTextNode("\n "));
+ basePointParams.appendChild(cofactor);
+ }
+
+ basePointParams.appendChild(factoryDoc.createTextNode("\n "));
+ explicitParams.appendChild(factoryDoc.createTextNode("\n "));
+
+ domainParameters.appendChild(factoryDoc.createTextNode("\n "));
+ domainParameters.appendChild(explicitParams);
+ domainParameters.appendChild(factoryDoc.createTextNode("\n "));
+ }
+ }
+
+ // Public key point
+ Element publicKeyPoint = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":PublicKey");
+
+ Element publicKeyX = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":X");
+ publicKeyX.setAttributeNS(xsiNS, xsiNSP + ":type", fieldElemTypeString);
+ publicKeyX.setAttributeNS(null, "Value",
+ (fieldId == Field.PRIME_FIELD)
+ ? publicKey.getW().getCoordinates().getX().getValue().toBigInt().toString(10)
+ : evenStringLength(publicKey.getW().getCoordinates().getX().getValue().toBigInt().toString(16)));
+ publicKeyPoint.appendChild(factoryDoc.createTextNode("\n "));
+ publicKeyPoint.appendChild(publicKeyX);
+
+ Element publicKeyY = factoryDoc.createElementNS(ecdsaNS, ecdsaNSP + ":Y");
+ publicKeyY.setAttributeNS(xsiNS, xsiNSP + ":type", fieldElemTypeString);
+ publicKeyY.setAttributeNS(null, "Value",
+ (fieldId == Field.PRIME_FIELD)
+ ? publicKey.getW().getCoordinates().getY().getValue().toBigInt().toString(10)
+ : evenStringLength(publicKey.getW().getCoordinates().getY().getValue().toBigInt().toString(16)));
+ publicKeyPoint.appendChild(factoryDoc.createTextNode("\n "));
+ publicKeyPoint.appendChild(publicKeyY);
+ publicKeyPoint.appendChild(factoryDoc.createTextNode("\n "));
+
+ eCDSAKeyValue.appendChild(factoryDoc.createTextNode("\n "));
+ eCDSAKeyValue.appendChild(publicKeyPoint);
+ eCDSAKeyValue.appendChild(factoryDoc.createTextNode("\n "));
+
+ return eCDSAKeyValue;
+ }
+ */
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static String getECDSANSPrefix(Element element)
+ {
+ // FIXXME: Review this function (GK, 11.06.2002) - should return a list of strings, since more than
+ // one NS prefix can be bound to the ECDSA namespace
+
+ HashMap inScopeNSAttrs = getInScopeNSAttrs(element);
+ Iterator inScopeNSAttrsIt = inScopeNSAttrs.keySet().iterator();
+ while (inScopeNSAttrsIt.hasNext())
+ {
+ Attr currentAttr = (Attr)inScopeNSAttrs.get(inScopeNSAttrsIt.next());
+ if (ECDSAConstants.NAMESPACE_ECDSAKEYVALUE_.equals(currentAttr.getValue()))
+ {
+ return ("xmlns".equals(currentAttr.getNodeName())) ? "" : currentAttr.getNodeName().substring(6);
+ }
+ }
+ return null;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ // Converts an octet string representation into an int array as needed for the IAIK ECC library
+ // String: rightmost byte is least significant byte
+ // IntArray: rightmost byte is LEAST significant byte
+ private static int[] octetString2IntArray(String octetString)
+ {
+ int byteCount = octetString.length()/2;
+ int[] intArray = new int[byteCount/4 + ((byteCount % 4 != 0) ? 1 : 0)];
+ for (int i = 0; i < byteCount; i++)
+ {
+ int oSStartPos = octetString.length() - (i + 1) * 2;
+ int currentByte = Integer.parseInt(octetString.substring(oSStartPos, oSStartPos + 2), 16);
+ intArray[i/4] += (currentByte & 0xFF) << ((i % 4) * 8);
+ }
+ return intArray;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ // Converts an octet string representation into a byte array as needed for the IAIK ECC library
+ // String: rightmost byte is least significant byte
+ // ByteArray: rightmost byte is MOST significant byte
+ private static byte[] octetString2ByteArray(String octetString)
+ {
+ int byteCount = octetString.length()/2;
+ byte[] byteArray = new byte[byteCount];
+ for (int i = 0; i < byteCount; i++)
+ {
+ int oSStartPos = octetString.length() - (i + 1) * 2;
+ byteArray[byteCount - i - 1] = (byte) Integer.parseInt(octetString.substring(
+ oSStartPos, oSStartPos + 2), 16);
+ }
+ return byteArray;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static String evenStringLength(String hexString)
+ {
+ return (hexString.length() % 2 != 0) ? "0" + hexString : hexString;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static Element getChildElement(Element parent, String namespace, String localName,
+ int instance)
+ {
+ NodeList namedElements = parent.getElementsByTagNameNS(namespace, localName);
+ if (namedElements.getLength() < instance) return null;
+ return (Element)namedElements.item(instance - 1);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static String getChildElementText(Element parent, String namespace, String localName,
+ int instance)
+ {
+ Element child = getChildElement(parent, namespace, localName, instance);
+ if (child == null) return null;
+ NodeList childNodes = child.getChildNodes();
+ int nodeCount = 0;
+ while (nodeCount < childNodes.getLength())
+ {
+ Node currentNode = childNodes.item(nodeCount);
+ if (currentNode.getNodeType() == Node.TEXT_NODE) return currentNode.getNodeValue();
+ nodeCount++;
+ }
+ return null;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static HashMap getInScopeNSAttrs(Element element)
+ {
+ // Get all ancestors of element
+ Vector ancestors = new Vector();
+ ancestors.add(element);
+ Node currentAncestor = element;
+ while ((currentAncestor = currentAncestor.getParentNode()) != null &&
+ currentAncestor.getNodeType() == Node.ELEMENT_NODE)
+ {
+ ancestors.add(currentAncestor);
+ }
+
+ // Scan all ancestors for NS attributes
+ HashMap inScopeNSAttrs = new HashMap();
+ for (int i = ancestors.size() - 1; i >= 0; i--)
+ {
+ Element currentAncestorElem = (Element)ancestors.get(i);
+ NamedNodeMap attrs = currentAncestorElem.getAttributes();
+ for (int j = 0; j < attrs.getLength(); j++)
+ {
+ Attr currentAttr = (Attr)attrs.item(j);
+ String currentAttrName = currentAttr.getNodeName();
+ if ("xmlns".equals(currentAttrName) || currentAttrName.startsWith("xmlns:"))
+ {
+ inScopeNSAttrs.put(currentAttrName, currentAttr);
+ }
+ }
+ }
+
+ // Check if default NS attribute is in list; if value is empty remove it from list
+ Attr defaultNSAttr = (Attr)inScopeNSAttrs.get("xmlns");
+ if (defaultNSAttr != null && "".equals(defaultNSAttr.getValue())) inScopeNSAttrs.remove("xmlns");
+
+ return inScopeNSAttrs;
+ }
+} \ No newline at end of file
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPRequestJSPForwarder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPRequestJSPForwarder.java
new file mode 100644
index 000000000..7c4731555
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPRequestJSPForwarder.java
@@ -0,0 +1,76 @@
+/*
+ * Created on 17.02.2004
+ *
+ * To change the template for this generated file go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+package at.gv.egovernment.moa.id.util;
+
+import java.io.IOException;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author rschamberger
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public class HTTPRequestJSPForwarder {
+
+ /**
+ * Forwards the HttpServletRequest to a customizable JSP Page and serves the Response. <br>
+ * <ul>
+ * <li>Logs the message</li>
+ * </ul>
+ *
+ * @param message message text
+ * @param jspPageURI URI of the JSP page
+ * @param context the servlet context of the servlet belonging to the req, resp
+ * @param req servlet request
+ * @param resp servlet response
+ */
+ public static void forwardNamed(
+ String message,
+ String jspPageURI,
+ ServletContext context,
+ HttpServletRequest req,
+ HttpServletResponse resp) {
+
+ if (null != message) {
+ Logger.info(message);
+ req.setAttribute("Message", message);
+ }
+
+ //forward this to the given jsp page where the HTML response is generated
+ try {
+ context.getRequestDispatcher(jspPageURI).forward(req, resp);
+ } catch (IOException e) {
+ Logger.error(e);
+ } catch (ServletException e) {
+ Logger.error(e);
+ }
+ }
+
+ /**
+ * Forwards the HttpServletRequest to the customizable JSP Page 'message.jsp' and serves the Response. <br>
+ * <ul>
+ * <li>Logs the message</li>
+ * </ul>
+ *
+ * @param message message text
+ * @param context the servlet context of the servlet belonging to the req, resp
+ * @param req servlet request
+ * @param resp servlet response
+ */
+ public static void forwardDefault(
+ String message,
+ ServletContext context,
+ HttpServletRequest req,
+ HttpServletResponse resp) {
+ forwardNamed(message, "/message.jsp", context, req, resp);
+ }
+} \ No newline at end of file
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java
new file mode 100644
index 000000000..035c47eb9
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java
@@ -0,0 +1,68 @@
+package at.gv.egovernment.moa.id.util;
+
+/**
+ * HTTP Utilities
+ *
+ * @author Rudolf Schamberger
+ * @version $Id$
+ */
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+/**
+ *
+ * @author Rudolf Schamberger
+ *
+ */
+public class HTTPUtils {
+
+ /**
+ * Utility used to obtainin correct encoded HTTP content.
+ * Reads a given Content adressed by HTTP-URL into String.
+ * Content encoding is considered by using the Content-Type HTTP header charset value.
+ * @param URL HTTP URL to read from.
+ * @return String representation of content
+ * @throws IOException on data-reading problems
+ */
+ public static String readHttpURL(String URL)
+ throws IOException {
+
+ URL url = new URL(URL);
+ HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+ conn.setRequestMethod("GET");
+ String contentType = conn.getContentType();
+ RE regExp = null;
+ try {
+ regExp = new RE("(;.*charset=)(\"*)(.*[^\"])");
+ } catch (RESyntaxException e) {
+ //RESyntaxException is not possible = expr. is costant
+ }
+ boolean charsetSupplied = regExp.match(contentType);
+ String encoding = "ISO-8859-1"; //default HTTP encoding
+ if (charsetSupplied) {
+ encoding = regExp.getParen(3);
+ }
+ InputStream instream = new BufferedInputStream(conn.getInputStream());
+ InputStreamReader isr = new InputStreamReader(instream, encoding);
+ Reader in = new BufferedReader(isr);
+ int ch;
+ StringBuffer buffer = new StringBuffer();
+ while ((ch = in.read()) > -1) {
+ buffer.append((char)ch);
+ }
+ in.close();
+ conn.disconnect();
+ return buffer.toString();
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java
new file mode 100644
index 000000000..4330133f0
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java
@@ -0,0 +1,374 @@
+/*
+ * Created on 01.10.2004
+ *
+ * @author rschamberger
+ * $ID$
+ */
+package at.gv.egovernment.moa.id.util;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.URLDecoder;
+
+/**
+ * Special ServletRequestWrapper class which provides a more precise implementation of the getParameter*
+ * family. This implementation cares about the order of the parameters from Query String and HTTP POST
+ * Body. Use this as Filter class for Servlets which such needs.
+ *
+ * @author Rudolf Schamberger
+ * @version $Id$
+ */
+public class InOrderServletRequestWrapper extends HttpServletRequestWrapper {
+
+ /**
+ * standard encoding used to decode the URL string.
+ */
+ //
+ public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
+ /**
+ * Vector that stores the order of the query paramters
+ */
+ private Vector queryParamOrder;
+
+ /**
+ * Hashtable that stores the content of the query paramters
+ */
+ private Hashtable queryParameters;
+
+ /**
+ * Vector that stores the order of the HTTP body paramters
+ */
+ private Vector bodyParamOrder;
+
+ /**
+ * Hashtable that stores the content of the HTTP body paramters
+ */
+ private Hashtable bodyParameters;
+
+ /**
+ * ServletContext
+ */
+ private ServletContext context;
+
+ /**
+ * Identifier used to identify query parameters
+ */
+ public static final int QUERY_PARAM = 1;
+
+ /**
+ * Identifier used to identify HTTP body parameters
+ */
+ public static final int BODY_PARAM = 2;
+
+ /**
+ * @see HttpServletRequestWrapper
+ */
+ public InOrderServletRequestWrapper(final HttpServletRequest request, final ServletContext sContext) {
+ super(request);
+ this.context = sContext;
+ }
+
+ /**
+ * parses the Query and if availlable also HTTP POST parameters
+ *
+ * @param req a <code>HttpServletRequest</code> which should be parsed
+ */
+ protected final void parseParameters(final HttpServletRequest req)
+ {
+ queryParamOrder = new Vector();
+ queryParameters = new Hashtable();
+ bodyParamOrder = new Vector();
+ bodyParameters = new Hashtable();
+
+ //Insert code for Query string parsing
+ String rawQuery = req.getQueryString();
+ queryParameters = tokenize(queryParameters, queryParamOrder, rawQuery, DEFAULT_CHARACTER_ENCODING, true);
+
+ //analyze HTTP Post body parameters
+ if (req.getMethod().equalsIgnoreCase("POST"))
+ {
+ //get body encoding
+ String enc = req.getCharacterEncoding();
+ if (enc == null) enc = DEFAULT_CHARACTER_ENCODING;
+
+ if (req.getContentType().equals("application/x-www-form-urlencoded"))
+ {
+ try
+ {
+ bodyParameters = parsePostData(bodyParameters, req.getContentLength(), req.getInputStream(), enc);
+ }
+ catch (IOException e)
+ {
+ context.log("could not open input stream of reqest \n" + e.toString());
+ }
+ }
+ else
+ {
+ //TODO add multipart code
+ context.log(
+ "ERROR other Content-Types than 'application/x-www-form-urlencoded' not supported!");
+ }
+
+ }// end POST
+ }
+
+ /**
+ * parses the HTTP POST parameters
+ *
+ * @param ht parameter Hashtable to put parameters in.
+ * @param length of content
+ * @param instream the ServletInputStream of the request
+ * @param encoding encoding of the instream
+ *
+ * @return the Hashtable with the parsed data
+ */
+ private Hashtable parsePostData(Hashtable ht, final int length, final ServletInputStream instream,
+ final String encoding)
+ {
+ int inputLen, offset;
+ byte[] postedBytes = null;
+ boolean dataRemaining = true;
+ String postedBody;
+
+ StringBuffer sb = new StringBuffer();
+
+ if (length <= 0)
+ {
+ return null;
+ }
+
+ postedBytes = new byte[length];
+ try
+ {
+ offset = 0;
+ while (dataRemaining)
+ {
+ inputLen = instream.read(postedBytes, offset, length - offset);
+ if (inputLen <= 0)
+ {
+ throw new IOException("read error during reading the HTTP POST body");
+ }
+ offset += inputLen;
+ if ((length - offset) == 0)
+ {
+ dataRemaining = false;
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ System.out.println("Exception =" + e);
+ return null;
+ }
+
+ postedBody = new String(postedBytes);
+ Hashtable ht2 = tokenize(ht, bodyParamOrder, postedBody, encoding, false);
+ return ht2;
+ }
+
+
+ /**
+ * tokenizes parameter strings
+ *
+ * @param ht parameter Hashtable to put parameters in.
+ * @param order Vector in which the order of the tokenized parameters will be stored.
+ * @param parameterString String to tokenize.
+ * @param encoding which will be used to decode the parameterString.
+ *
+ * @return the Hashtable with the parsed data
+ */
+ private Hashtable tokenize(Hashtable ht, Vector order, final String parameterString, final String encoding, boolean decode)
+ {
+ String[] valArray = null;
+
+ if (null == parameterString) return ht;
+
+ StringTokenizer st = new StringTokenizer(parameterString, "&");
+
+ String key = null;
+ String val = null;
+
+ while (st.hasMoreTokens())
+ {
+ String pair = (String) st.nextToken();
+ int pos = pair.indexOf('=');
+ if (pos == -1)
+ {
+ throw new IllegalArgumentException();
+ }
+ try
+ {
+ if (decode) {
+ key = URLDecoder.decode(pair.substring(0, pos), encoding);
+ val = URLDecoder.decode(pair.substring(pos + 1, pair.length()), encoding);
+ } else {
+ key = pair.substring(0, pos);
+ val = pair.substring(pos + 1, pair.length());
+ }
+ //Logger.debug("(" + Integer.toString(key.length()) + "=" + Integer.toString(pair.substring(0, pos).length()) + ")"+key+"|--|"+pair.substring(0, pos));
+ //Logger.debug("(" + Integer.toString(val.length()) + "=" + Integer.toString(pair.substring(pos + 1, pair.length()).length()) + ")"+val+"|--|"+pair.substring(pos + 1, pair.length()));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException();
+ }
+ if (ht.containsKey(key))
+ {
+ String oldVals[] = (String[]) ht.get(key);
+ valArray = new String[oldVals.length + 1];
+ for (int i = 0; i < oldVals.length; i++)
+ {
+ valArray[i] = oldVals[i];
+ }
+ valArray[oldVals.length] = val;
+ }
+ else
+ {
+ valArray = new String[1];
+ valArray[0] = val;
+ }
+ ht.put(key, valArray);
+ order.addElement(key);
+ }
+ return ht;
+
+ }
+
+ /**
+ * Returns the value of a request parameter as a <code>String</code>, or <code>null</code> if the
+ * parameter does not exist. Request parameters are extra information sent with the request. For HTTP
+ * servlets, parameters are contained in the query string or posted form data.
+ *
+ * <p>
+ * You should only use this method when you are sure the parameter has only one value. If the parameter
+ * might have more than one value, use {@link #getParameterValues(String, int)}.
+ *
+ * <p>
+ * If you use this method with a multivalued parameter, the value returned is equal to the first value in
+ * the array returned by <code>getParameterValues</code>.
+ *
+ * <p>
+ * If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then
+ * reading the body directly via {@link #getInputStream} or {@link #getReader}can interfere with the
+ * execution of this method.
+ *
+ * @param name a <code>String</code> containing the name of the parameter whose value is requested
+ *
+ * @return a <code>String</code> representing the single value of the parameter
+ *
+ * @see #getParameterValues(String, int)
+ *
+ */
+ public final String getParameter(final String name) {
+ String val = getParameter(name, QUERY_PARAM);
+ return (null != val) ? val : getParameter(name, BODY_PARAM);
+ }
+
+ /**
+ * Returns the value of a request parameter as a <code>String</code>, or <code>null</code> if the
+ * parameter does not exist.
+ *
+ * @param name a <code>String</code> containing the name of the parameter whose value is requested
+ * @param parameterType type of parameter
+ * @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#QUERY_PARAM
+ * and @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#BODY_PARAM
+ * @see #getParameterValues(String)
+ * @return value of the (single) parameter or null if not availlable
+ **/
+ public final String getParameter(final String name, final int parameterType)
+ {
+
+ Hashtable parameters = (parameterType == QUERY_PARAM) ? queryParameters : bodyParameters;
+ String[] vals = (String[]) parameters.get(name);
+ if (vals == null)
+ {
+ return null;
+ }
+ return vals[0];
+ }
+
+
+ /**
+ * Returns an array of <code>String</code> objects containing all of the values the given request
+ * parameter has, or <code>null</code> if the parameter does not exist.
+ *
+ * <p>
+ * If the parameter has a single value, the array has a length of 1.
+ *
+ * @param name a <code>String</code> containing the name of the parameter whose value is requested
+ * @param parameterType type of parameter
+ * @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#QUERY_PARAM
+ * and @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#BODY_PARAM
+ * @return an array of <code>String</code> objects containing the parameter's values or null
+ *
+ * @see #getParameter
+ */
+ public final String getParameterValues(final String name, final int parameterType)
+ {
+ Hashtable parameters = (parameterType == QUERY_PARAM) ? queryParameters : bodyParameters;
+ String[] vals = (String[]) parameters.get(name);
+ if (vals == null)
+ {
+ return null;
+ }
+ String vallist = vals[0];
+ for (int i = 1; i < vals.length; i++)
+ {
+ vallist = vallist + "," + vals[i];
+ }
+ return vallist;
+ }
+
+ /**
+ *
+ * Returns an <code>Enumeration</code> of <code>String</code> objects containing the names of the
+ * parameters. If there are no parameters, the method returns an empty
+ * <code>Enumeration</code>.
+ *
+ * @return an <code>Enumeration</code> of <code>String</code> objects, each <code>String</code>
+ * containing the name of a request parameter; or an empty <code>Enumeration</code> if the
+ * request has no parameters
+ *
+ */
+ public final Enumeration getParameterNames()
+ {
+ Vector FullParamOrder = new Vector();
+ for (Enumeration enu = queryParamOrder.elements(); enu.hasMoreElements();) {
+ FullParamOrder.addElement(enu.nextElement());
+ }
+ for (Enumeration enu = bodyParamOrder.elements(); enu.hasMoreElements();) {
+ FullParamOrder.addElement(enu.nextElement());
+ }
+ return FullParamOrder.elements();
+ }
+
+ /**
+ *
+ * Returns an <code>Enumeration</code> of <code>String</code> objects containing the names of the
+ * parameters contained in this request. If the request has no parameters, the method returns an empty
+ * <code>Enumeration</code>.
+ * @param parameterType type of parameter
+ *
+ * @return an <code>Enumeration</code> of <code>String</code> objects, each <code>String</code>
+ * containing the name of a request parameter; or an empty <code>Enumeration</code> if the
+ * request has no parameters
+ *
+ */
+ public final Enumeration getParameterNames(final int parameterType)
+ {
+ if (QUERY_PARAM == parameterType)
+ return queryParamOrder.elements();
+ else
+ return bodyParamOrder.elements();
+ }
+} //End InOrderServletRequestWrapper \ No newline at end of file
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/MOAIDMessageProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/MOAIDMessageProvider.java
new file mode 100644
index 000000000..d31aa6ec1
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/MOAIDMessageProvider.java
@@ -0,0 +1,58 @@
+package at.gv.egovernment.moa.id.util;
+
+import java.util.Locale;
+
+import at.gv.egovernment.moa.util.Messages;
+
+/**
+ * A singleton wrapper around a <code>Message</code> object, providing the messages used in MOA-ID.
+ *
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class MOAIDMessageProvider {
+
+ /** DEFAULT_MESSAGE_RESOURCES are resources/properties/id_messages */
+ private static final String[] DEFAULT_MESSAGE_RESOURCES =
+ { "resources/properties/id_messages" };
+ /** DEFAULT_MESSAGE_LOCALES are "de", "AT" */
+ private static final Locale[] DEFAULT_MESSAGE_LOCALES =
+ new Locale[] { new Locale("de", "AT") };
+ /** The instance for our singleton */
+ private static MOAIDMessageProvider instance;
+ /** The Messages */
+ private Messages messages;
+
+ /**
+ * Returns the single instance of <code>MOAIDMessageProvider</code>.
+ *
+ * @return the single instance of <code>MOAIDMessageProvider</code>
+ */
+ public static MOAIDMessageProvider getInstance() {
+ if (instance == null)
+ instance = new MOAIDMessageProvider(DEFAULT_MESSAGE_RESOURCES, DEFAULT_MESSAGE_LOCALES);
+ return instance;
+ }
+
+ /**
+ * Create a <code>MOAIDMessageProvider</code>.
+ *
+ * @param resourceNames The names of the resources containing the messages.
+ * @param locales The corresponding locales.
+ */
+ protected MOAIDMessageProvider(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);
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java
new file mode 100644
index 000000000..3f5fddba2
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java
@@ -0,0 +1,62 @@
+package at.gv.egovernment.moa.id.util;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author rschamberger
+ *
+ */
+/**
+ * A Filter class wich uses the InOrderServletRequestWrapper to provide servlets a more precise
+ * implementation of the getParameter* family. This implementation cares about the order of the parameters
+ * from Query String and HTTP POST Body. Use this as Filter class for Servlets which such needs.
+ *
+ * @author Rudolf Schamberger
+ * @version $Id$
+ */
+public class ParameterInOrderFilter implements Filter
+{
+
+ /**
+ * filterConfig
+ */
+ private FilterConfig filterConfig;
+
+ /**
+ * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+ */
+ public final void init(final FilterConfig config)
+ {
+ this.filterConfig = config;
+ }
+
+ /**
+ * @see javax.servlet.Filter#destroy()
+ */
+ public final void destroy()
+ {
+ };
+
+ /**
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
+ * javax.servlet.FilterChain)
+ */
+ public final void doFilter(final ServletRequest request, final ServletResponse response,
+ final FilterChain chain) throws IOException, ServletException
+ {
+ InOrderServletRequestWrapper sRequ = new InOrderServletRequestWrapper((HttpServletRequest) request,
+ filterConfig.getServletContext());
+ //parse the Query (and Body) parameters
+ sRequ.parseParameters((HttpServletRequest) request);
+ //process the rest of filter chain
+ chain.doFilter(sRequ, response);
+ }
+} \ No newline at end of file
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java
new file mode 100644
index 000000000..da75b4213
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java
@@ -0,0 +1,22 @@
+package at.gv.egovernment.moa.id.util;
+
+import java.util.Date;
+
+/**
+ * Random number generator used to generate ID's
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class Random {
+
+ /** random number generator used */
+ private static java.util.Random random = new java.util.Random(new Date().getTime());
+ /**
+ * Creates a new random number, to be used as an ID.
+ *
+ * @return random long as a String
+ */
+ public static String nextRandom() {
+ return "" + random.nextLong();
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java
new file mode 100644
index 000000000..9fa0803c4
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java
@@ -0,0 +1,180 @@
+package at.gv.egovernment.moa.id.util;
+
+import iaik.pki.PKIConfiguration;
+import iaik.pki.PKIException;
+import iaik.pki.PKIFactory;
+import iaik.pki.PKIProfile;
+import iaik.pki.jsse.IAIKX509TrustManager;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.Security;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.ConfigurationProvider;
+import at.gv.egovernment.moa.id.config.ConnectionParameter;
+import at.gv.egovernment.moa.id.iaik.config.PKIConfigurationImpl;
+import at.gv.egovernment.moa.id.iaik.pki.PKIProfileImpl;
+import at.gv.egovernment.moa.id.iaik.pki.jsse.MOAIDTrustManager;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * Utility for a obtaining a secure socket factory using <code>IAIKX509TrustManager</code>.
+ * This <code>TrustManager</code> implementation features CRL checking.<br/>
+ * <code>SSLUtils</code> caches secure socket factories for given <code>ConnectionParameter</code>s.
+ *
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class SSLUtils {
+
+ /** SSLSocketFactory store, mapping URL->SSLSocketFactory **/
+ private static Map sslSocketFactories = new HashMap();
+
+ /**
+ * Initializes the SSLSocketFactory store.
+ */
+ public static void initialize() {
+ sslSocketFactories = new HashMap();
+ Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+ System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
+ }
+
+ /**
+ * Creates an <code>SSLSocketFactory</code> which utilizes an
+ * <code>IAIKX509TrustManager</code> for the given trust store,
+ * and the given key store.
+ *
+ * @param conf configuration provider providing a generic properties pointing
+ * to trusted CA store and certificate store root
+ * @param connParam connection parameter containing the client key store settings
+ * to be used in case of client authentication;
+ * if <code>connParam.getClientKeyStore() == null</code>, client authentication
+ * is assumed to be disabled
+ * @return <code>SSLSocketFactory</code> to be used by an <code>HttpsURLConnection</code>
+ * @throws IOException thrown while reading key store file
+ * @throws GeneralSecurityException thrown while creating the socket factory
+ * @throws ConfigurationException on invalid configuration data
+ * @throws PKIException while initializing the <code>IAIKX509TrustManager</code>
+ */
+ public static SSLSocketFactory getSSLSocketFactory(
+ ConfigurationProvider conf,
+ ConnectionParameter connParam)
+ throws IOException, GeneralSecurityException, ConfigurationException, PKIException {
+
+ Logger.debug("Get SSLSocketFactory for " + connParam.getUrl());
+ // retrieve SSLSocketFactory if already created
+ SSLSocketFactory ssf = (SSLSocketFactory)sslSocketFactories.get(connParam.getUrl());
+ if (ssf != null)
+ return ssf;
+ // else create new SSLSocketFactory
+ String trustStoreURL = conf.getTrustedCACertificates();
+ if (trustStoreURL == null)
+ throw new ConfigurationException(
+ "config.08", new Object[] {"TrustedCACertificates"});
+ String acceptedServerCertURL = connParam.getAcceptedServerCertificates();
+ TrustManager[] tms = getTrustManagers(conf, trustStoreURL, acceptedServerCertURL);
+ KeyManager[] kms = at.gv.egovernment.moa.util.SSLUtils.getKeyManagers(
+ "pkcs12", connParam.getClientKeyStore(), connParam.getClientKeyStorePassword());
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ ctx.init(kms, tms, null);
+ ssf = ctx.getSocketFactory();
+ // store SSLSocketFactory
+ sslSocketFactories.put(connParam.getUrl(), ssf);
+ return ssf;
+ }
+
+ /**
+ * Initializes an <code>IAIKX509TrustManager</code> for a given trust store,
+ * using configuration data.
+ *
+ * @param conf MOA-ID configuration provider
+ * @param trustStoreURL trust store URL
+ * @param acceptedServerCertURL file URL pointing to directory containing accepted server SSL certificates
+ * @return <code>TrustManager</code> array containing the <code>IAIKX509TrustManager</code>
+ * @throws ConfigurationException on invalid configuration data
+ * @throws IOException on data-reading problems
+ * @throws PKIException while initializing the <code>IAIKX509TrustManager</code>
+ */
+ public static TrustManager[] getTrustManagers(
+ ConfigurationProvider conf, String trustStoreURL, String acceptedServerCertURL)
+ throws ConfigurationException, PKIException, IOException, GeneralSecurityException {
+
+ PKIConfiguration cfg = null;
+ if (! PKIFactory.getInstance().isAlreadyConfigured())
+ cfg = new PKIConfigurationImpl(conf);
+ String boolString = conf.getGenericConfigurationParameter(ConfigurationProvider.TRUST_MANAGER_REVOCATION_CHECKING);
+ //not using BoolUtils because default value hast to be true!
+ boolean checkRevocation = !("false".equals(boolString) || "0".equals(boolString));
+ PKIProfile profile = new PKIProfileImpl(trustStoreURL, checkRevocation);
+ // This call fixes a bug occuring when PKIConfiguration is
+ // initialized by the MOA-SP initialization code, in case
+ // MOA-SP is called by API
+ MOAIDTrustManager.initializeLoggingContext();
+ IAIKX509TrustManager tm = new MOAIDTrustManager(acceptedServerCertURL);
+ tm.init(cfg, profile);
+ return new TrustManager[] {tm};
+ }
+ /**
+ * Reads a file, given by URL, into a byte array,
+ * securing the connection by IAIKX509TrustManager.
+ * @param connParam containing URL and accepted server certificates
+ * @param conf ConfigurationProvider for reading
+ * @return String representation of content
+ * @throws ConfigurationException on invalid configuration data
+ * @throws PKIException on invalid configuration data
+ * @throws IOException on data-reading problems
+ * @throws GeneralSecurityException on security issues
+ */
+ public static String readHttpsURL(ConfigurationProvider conf, ConnectionParameter connParam)
+ throws ConfigurationException, PKIException, IOException, GeneralSecurityException {
+
+ URL url = new URL(connParam.getUrl());
+ HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
+ conn.setRequestMethod("GET");
+ conn.setDoInput(true);
+ SSLSocketFactory sslSocketFactory = getSSLSocketFactory(conf, connParam);
+ conn.setSSLSocketFactory(sslSocketFactory);
+ conn.connect();
+ String contentType = conn.getContentType();
+ RE regExp = null;
+ try {
+ regExp = new RE("(;.*charset=)(\"*)(.*[^\"])");
+ } catch (RESyntaxException e) {
+ //RESyntaxException is not possible = expr. is costant
+ }
+ boolean charsetSupplied = regExp.match(contentType);
+ String encoding = "ISO-8859-1"; //default HTTP encoding
+ if (charsetSupplied) {
+ encoding = regExp.getParen(3);
+ }
+ InputStream instream = new BufferedInputStream(conn.getInputStream());
+ InputStreamReader isr = new InputStreamReader(instream, encoding);
+ Reader in = new BufferedReader(isr);
+ int ch;
+ StringBuffer buffer = new StringBuffer();
+ while ((ch = in.read()) > -1) {
+ buffer.append((char)ch);
+ }
+ in.close();
+ conn.disconnect();
+ return buffer.toString();
+ }
+}