diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util')
16 files changed, 3086 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..70c397c42 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/AxisSecureSocketFactory.java @@ -0,0 +1,236 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +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..9b08ed4b1 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAConstants.java @@ -0,0 +1,60 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +/* + * 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..e1ef1af08 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java @@ -0,0 +1,596 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +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..ac34d31dc --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPRequestJSPForwarder.java @@ -0,0 +1,100 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +/* + * 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..7b29051f3 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java @@ -0,0 +1,92 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +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..74b18a662 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java @@ -0,0 +1,412 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +/* + * 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) { + if (pos == -1) { // query is not a key=value pair, it is just a key + key = URLDecoder.decode(pair, encoding); + val = ""; // value is empty string + } + else { + key = URLDecoder.decode(pair.substring(0, pos), encoding); + val = URLDecoder.decode(pair.substring(pos + 1, pair.length()), encoding); + } + } else { + if (pos == -1) { // query is not a key=value pair, it is just a key + key = pair; + val = ""; // value is empty string + } + 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) + { + Logger.error("Error encoding query", 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..a4d0c2ab6 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/MOAIDMessageProvider.java @@ -0,0 +1,82 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +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/ParamValidatorUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java new file mode 100644 index 000000000..790651adf --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java @@ -0,0 +1,538 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.util;
+
+import java.io.IOException; +import java.io.StringReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.logging.Logger; +
+
+public class ParamValidatorUtils {
+
+ /**
+ * Checks if the given target is valid
+ * @param target HTTP parameter from request
+ * @return
+ */
+ public static boolean isValidTarget(String target) {
+
+ Logger.debug("Überprüfe Parameter Target");
+
+ // if non parameter is given return true
+ if (target == null) {
+ Logger.debug("Parameter Target ist null");
+ return true;
+ }
+
+
+ Pattern pattern = Pattern.compile("[a-zA-Z-]{1,5}");
+ Matcher matcher = pattern.matcher(target);
+ boolean b = matcher.matches();
+ if (b) {
+ Logger.debug("Parameter Target erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter Target. Target entspricht nicht den Kriterien (nur Zeichen a-z, A-Z und -, sowie 1-5 Zeichen lang)");
+ return false;
+ }
+
+ } + + /** + * Checks if the given target is valid + * @param sourceID HTTP parameter from request + * @return + */ + public static boolean isValidSourceID(String sourceID) { + + Logger.debug("Überprüfe Parameter sourceID"); + + // if non parameter is given return true + if (sourceID == null) { + Logger.debug("Parameter Target ist null"); + return true; + } + + + Pattern pattern = Pattern.compile("[\\w-_]{1,20}"); + Matcher matcher = pattern.matcher(sourceID); + boolean b = matcher.matches(); + if (b) { + Logger.debug("Parameter sourceID erfolgreich überprüft"); + return true; + } + else { + Logger.error("Fehler Überprüfung Parameter sourceID. SourceID entspricht nicht den Kriterien (nur Zeichen a-z, A-Z, - und _, sowie 1-20 Zeichen lang)"); + return false; + } + + }
+
+ /**
+ * Checks if the given useMandate is valid
+ * @param target HTTP parameter from request
+ * @return
+ */
+ public static boolean isValidUseMandate(String usemandate) {
+
+ Logger.debug("Überprüfe Parameter useMandate");
+
+ // if non parameter is given return true
+ if (usemandate== null) {
+ Logger.debug("Parameter useMandate ist null");
+ return true;
+ }
+
+
+ if (usemandate.compareToIgnoreCase("true") == 0 || usemandate.compareToIgnoreCase("false") == 0) {
+ Logger.debug("Parameter useMandate erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter useMandate. useMandate ist weder 'true' noch 'false')");
+ return false;
+ }
+
+
+
+
+
+ }
+
+ /**
+ * Checks if the given bkuURI is valid
+ * @param target HTTP parameter from request
+ * @return
+ */
+ public static boolean isValidBKUURI(String bkuURI) {
+ Logger.debug("Überprüfe Parameter bkuURI"); +
+ // if non parameter is given return true
+ if (bkuURI == null) {
+ Logger.debug("Parameter bkuURI ist null");
+ return true;
+ }
+
+ // check if template is a valid URL
+ try {
+ // check if bku url starts with http or https
+ if (bkuURI.startsWith("http") || bkuURI.startsWith("https")) {
+ URL url =new URL(bkuURI);
+
+ // check if bkuURI is a local BKU
+ if (bkuURI.compareToIgnoreCase("https://localhost:3496/https-security-layer-request") == 0 ||
+ bkuURI.compareToIgnoreCase("http://localhost:3495/http-security-layer-request") == 0 || + bkuURI.compareToIgnoreCase("http://127.0.0.1:3495/http-security-layer-request") == 0 || + bkuURI.compareToIgnoreCase("https://127.0.0.1:3496/https-security-layer-request") == 0) {
+ Logger.debug("Parameter bkuURI erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.debug("Parameter bkuURI ist keine lokale BKU. Überprüfe Liste der vertrauenswürdigen BKUs.");
+ AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
+ List trustedBKUs = authConf.getTrustedBKUs();
+ boolean b = trustedBKUs.contains(bkuURI);
+ if (b) {
+ Logger.debug("Parameter bkuURI erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI ist nicht auf Liste der vertrauenswürdigen BKUs (Konfigurationselement: MOA-IDConfiguration/TrustedBKUs)");
+ return false;
+ }
+ }
+
+
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI beginnt nicht mit http or https");
+ return false;
+ }
+
+
+ } catch (MalformedURLException e) {
+ Logger.error("Fehler Überprüfung Parameter bkuURI", e);
+ return false;
+ } catch (ConfigurationException e) {
+ Logger.error("Fehler Überprüfung Parameter bkuURI", e);
+ return false;
+ }
+ }
+
+// private static boolean testBKUConnection(URL url) {
+//
+// // make NullOperationRequest
+// //String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sl:NullOperationRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\"/>";
+// String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sl:GetPropertiesRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\"/>";
+//
+// HttpURLConnection connection;
+// if (url != null) {
+// try {
+// if (url.toExternalForm().startsWith("https")) {
+// connection = (HttpsURLConnection)url.openConnection();
+// }
+// else {
+// connection = (HttpURLConnection)url.openConnection();
+// }
+//
+// connection.setRequestMethod("POST");
+// connection.setDoOutput(true);
+//
+// connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+//
+// String toSend = URLEncoder.encode(request, "UTF-8");
+// toSend = "XMLRequest=" + toSend;
+// connection.setRequestProperty("Content-Length", String.valueOf(toSend.getBytes().length));
+//
+// Logger.debug("Send NullOperationRequest to BKU.");
+//
+// OutputStream out = connection.getOutputStream();
+// out.write(toSend.getBytes());
+//
+// // get response
+// connection.connect();
+// int responseCode = connection.getResponseCode();
+//
+// if (responseCode != 200) {
+// InputStream is = connection.getErrorStream();
+// int ch;
+// String ret = "";
+// while ((ch = is.read()) != -1)
+// ret += (char)ch;
+//
+// is.close();
+//
+// System.out.println("ret: " + ret);
+//
+// Logger.error("Fehler Überprüfung Parameter bkuURI. Antwortcode von BKU ist nicht 200.");
+// return false;
+// }
+//
+// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+// factory.setNamespaceAware(true);
+// DocumentBuilder builder = factory.newDocumentBuilder();
+//
+// //Document doc = builder.parse(connection.getInputStream());
+//
+// System.out.println(convertStreamToString(connection.getInputStream()));
+//
+//// NodeList l = doc.getElementsByTagNameNS(Constants.SL12_NS_URI, "ErrorResponse");
+//// if (l.getLength() != 0) {
+//// Logger.error("Fehler Überprüfung Parameter bkuURI. ErrorResponse von BKU empfangen.");
+//// return false;
+//// }
+//
+// Logger.debug("Parameter Template bkuURI erfolgreich überprüft");
+// return true;
+//
+//// } catch (SAXException e) {
+//// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+//// return false;
+// } catch (IOException e) {
+// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+// return false;
+// } catch (ParserConfigurationException e) {
+// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+// return false;
+// }
+// }
+// else {
+// Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI ist null.");
+// return false;
+// }
+//
+//
+// }
+
+// public static String convertStreamToString(InputStream is) {
+// if (is != null) {
+// Writer writer = new StringWriter();
+//
+// char[] buffer = new char[1024];
+// try {
+// Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+// int n;
+// while ((n = reader.read(buffer)) != -1) {
+// writer.write(buffer, 0, n);
+// }
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+//
+// return writer.toString();
+// }
+// else {
+// return "";
+// }
+// }
+
+ /**
+ * Checks if the given template is valid
+ * @param req
+ * @param template
+ * @return
+ */
+ public static boolean isValidTemplate(HttpServletRequest req, String template) {
+
+ Logger.debug("Überprüfe Parameter Template bzw. bkuSelectionTemplateURL");
+
+ // if non parameter is given return true
+ if (template == null) {
+ Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL ist null");
+ return true;
+ }
+
+ // check if template is a valid URL
+ try {
+
+ // check if template url starts with http or https
+ if (template.startsWith("http") || template.startsWith("https")) {
+
+ // check if template url is from same server
+ String name = req.getServerName();
+ String httpName = "http://" + name;
+ String httpsName = "https://" + name;
+
+ if (template.startsWith(httpName) || template.startsWith(httpsName)) {
+ new URL(template);
+ Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL. Parameter liegt nicht am gleichen Server wie die MOA-Instanz (" + req.getServerName() + ")");
+ return false;
+ }
+
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL. Paramter beginnt nicht mit http oder https.");
+ return false;
+ }
+
+
+ } catch (MalformedURLException e) {
+ Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL.", e);
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the given template is valid
+ * @param target HTTP parameter from request
+ * @return
+ */
+ public static boolean isValidSessionID(String sessionID) {
+ Logger.debug("Überprüfe Parameter MOASessionId");
+
+ // if non parameter is given return true
+ if (sessionID == null) {
+ Logger.debug("Parameter MOASessionId ist null");
+ return true;
+ }
+
+
+ Pattern pattern = Pattern.compile("[0-9-]*");
+ Matcher matcher = pattern.matcher(sessionID);
+ boolean b = matcher.matches();
+ if (b) {
+ Logger.debug("Parameter MOASessionId erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter MOASessionId. MOASessionId entspricht nicht den Kriterien (nur Zeichen 0-9 und -)");
+ return false;
+ }
+
+
+
+
+
+ }
+
+ /**
+ * Checks if the given oa is valid
+ * @param target HTTP parameter from request
+ * @return
+ */
+ public static boolean isValidOA(String oa) {
+ Logger.debug("Überprüfe Parameter oa");
+ // if non parameter is given return true
+ if (oa == null) {
+ Logger.debug("Parameter oa ist null");
+ return true;
+ }
+
+ // check if template is a valid URL
+ try {
+
+ // check if template url starts with http or https
+ if (oa.startsWith("http") || oa.startsWith("https")) {
+ new URL(oa);
+ Logger.debug("Parameter oa erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter oa. oa beginnt nicht mit http or https");
+ return false;
+ }
+
+ } catch (MalformedURLException e) {
+ Logger.error("Fehler Überprüfung Parameter oa", e);
+ return false;
+ }
+
+ }
+
+ /**
+ * Checks if the given signurl is valid
+ * @param target HTTP parameter from request
+ * @return
+ */
+ public static boolean isValidSignUrl(String signurl) {
+
+ Logger.debug("Überprüfe Parameter signurl");
+
+ // if non parameter is given return true
+ if (signurl == null) {
+ Logger.debug("Parameter signurl ist null");
+ return true;
+ }
+
+ // check if template is a valid URL
+ try {
+
+ // check if signurl starts with http or https
+ if (signurl.startsWith("http") || signurl.startsWith("https")) {
+ new URL(signurl);
+ Logger.debug("Parameter signurl erfolgreich überprüft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler Überprüfung Parameter signurl. signurl beginnt nicht mit http or https");
+ return false;
+ }
+
+ } catch (MalformedURLException e) {
+ Logger.error("Fehler Überprüfung Parameter signurl", e);
+ return false;
+ }
+
+ }
+
+ /**
+ * Checks if <BKU>, <XMLRequest>, <DataURL>, <CertInfoXMLRequest>,
+ * <CertInfoDataURL> placeholders are contained in the given string.
+ * The placeholder <PushInfobox> is not checked, as it is only required,
+ * if other infoboxes as identity link will be treated.
+ * @param data
+ * @return
+ */
+// private static boolean checkPlaceHolders(String data) {
+//
+// boolean bku = data.contains("<BKU>");
+// boolean xmlrequest = data.contains("<XMLRequest>");
+// boolean dataurl = data.contains("<DataURL>");
+// boolean certinfoxmlrequest = data.contains("<CertInfoXMLRequest>");
+// boolean certinfodataurl = data.contains("<CertInfoDataURL>");
+//
+// System.out.println("Check Data: ");
+// System.out.println("bku: " + bku);
+// System.out.println("xmlrequest: " + xmlrequest);
+// System.out.println("dataurl: " + dataurl);
+// System.out.println("certinfoxmlrequest: " + certinfoxmlrequest);
+// System.out.println("certinfodataurl: " + certinfodataurl);
+//
+//
+// //return bku && xmlrequest && dataurl && certinfoxmlrequest && certinfodataurl;
+// return true;
+//
+// }
+
+
+// /**
+// * Converts an input stream to a string
+// * @param is
+// * @return
+// * @throws Exception
+// */
+// private static String convertStreamToString(InputStream is) throws Exception {
+// BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+// StringBuilder sb = new StringBuilder();
+// String line = null;
+// while ((line = reader.readLine()) != null) {
+// sb.append(line);
+// }
+// is.close();
+// return sb.toString();
+// }
+
+ public static boolean isValidXMLDocument(String document) {
+ +
+ if (document == null)
+ return false;
+
+ Logger.debug("Überprüfe Parameter XMLDocument");
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ InputSource is = new InputSource(new StringReader(document));
+ builder.parse(is);
+
+ Logger.debug("Parameter XMLDocument erfolgreich überprüft");
+ return true;
+
+ } catch (ParserConfigurationException e) {
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ return false;
+ } catch (SAXException e) {
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ return false;
+ } catch (IOException e) {
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ return false;
+ }
+
+ }
+
+}
+
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..a9d95d65e --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java @@ -0,0 +1,86 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +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..d006dcdfc --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java @@ -0,0 +1,55 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.util; + +import java.nio.ByteBuffer; +import java.security.SecureRandom; + +/** + * Random number generator used to generate ID's + * @author Paul Ivancsics + * @version $Id$ + */ +public class Random { + + /** random number generator used */ + private static SecureRandom random = new SecureRandom(); + /** + * Creates a new random number, to be used as an ID. + * + * @return random long as a String + */ + public static String nextRandom() { + + byte[] b = new byte[16]; // 16 bytes = 128 bits + random.nextBytes(b); + + + ByteBuffer bb = ByteBuffer.wrap(b); + long l = bb.getLong(); + + return "" + l; + } +} 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..a0add1054 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java @@ -0,0 +1,214 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +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 iaik.security.provider.IAIK; + +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(); + // JSSE Abhängigkeit + //Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); + Security.addProvider(new IAIK()); + //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(); + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ServletUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ServletUtils.java new file mode 100644 index 000000000..2ff9e5210 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ServletUtils.java @@ -0,0 +1,149 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +/**
+ *
+ */
+package at.gv.egovernment.moa.id.util;
+
+import java.io.IOException; +import java.io.OutputStream; +import java.net.URLEncoder; + +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.MOAIDException; +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.logging.Logger; +
+/**
+ * @author <a href="mailto:peter.danner@egiz.gv.at">Peter Danner</a>
+ *
+ */
+public class ServletUtils {
+
+ /**
+ * Writes out whether the CreateXMLSignatureRequest or a Redirect for form input processing
+ * depending on the requests starting text.
+ *
+ * @param resp The httpServletResponse
+ * @param session The current AuthenticationSession
+ * @param createXMLSignatureRequestOrRedirect The request
+ * @param servletGoal The servlet to which the redirect should happen
+ * @param servletName The servlet name for debug purposes
+ * @throws MOAIDException
+ * @throws IOException
+ */
+ public static void writeCreateXMLSignatureRequestOrRedirect(HttpServletResponse resp, AuthenticationSession session, String createXMLSignatureRequestOrRedirect, String servletGoal, String servletName)
+ throws MOAIDException,
+ IOException
+ {
+ if (!createXMLSignatureRequestOrRedirect.startsWith("Redirect")) {
+ resp.setStatus(307);
+ String dataURL = new DataURLBuilder().buildDataURL(
+ session.getAuthURL(), AuthenticationServer.REQ_VERIFY_AUTH_BLOCK, session.getSessionID());
+ resp.addHeader("Location", dataURL);
+
+ //TODO test impact of explicit setting charset with older versions of BKUs (HotSign)
+ resp.setContentType("text/xml;charset=UTF-8");
+
+ OutputStream out = resp.getOutputStream();
+ out.write(createXMLSignatureRequestOrRedirect.getBytes("UTF-8"));
+ out.flush();
+ out.close();
+ Logger.debug("Finished POST " + servletName); +
+ } else {
+ String redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(), servletGoal, session.getSessionID());
+ resp.setContentType("text/html");
+ resp.setStatus(302);
+ resp.addHeader("Location", redirectURL);
+ Logger.debug("REDIRECT TO: " + redirectURL);
+
+ }
+ } + /** + * Writes out whether the CreateXMLSignatureRequest or a Redirect for form input processing + * depending on the requests starting text. + * + * @param resp The httpServletResponse + * @param session The current AuthenticationSession + * @param createXMLSignatureRequestOrRedirect The request + * @param servletGoal The servlet to which the redirect should happen + * @param servletName The servlet name for debug purposes + * @throws MOAIDException + * @throws IOException + */ + public static void writeCreateXMLSignatureRequest(HttpServletResponse resp, AuthenticationSession session, String createXMLSignatureRequestOrRedirect, String servletGoal, String servletName, String dataURL) + throws MOAIDException, + IOException + { + resp.setStatus(307); + resp.addHeader("Location", dataURL); + + //TODO test impact of explicit setting charset with older versions of BKUs (HotSign) + resp.setContentType("text/xml;charset=UTF-8"); + + OutputStream out = resp.getOutputStream(); + out.write(createXMLSignatureRequestOrRedirect.getBytes("UTF-8")); + out.flush(); + out.close(); + Logger.debug("Finished POST " + servletName); + + }
+ + /** + * Writes out whether the CreateXMLSignatureRequest or a Redirect for form input processing + * depending on the requests starting text. + * + * @param resp The httpServletResponse + * @param session The current AuthenticationSession + * @param createXMLSignatureRequestOrRedirect The request + * @param servletGoal The servlet to which the redirect should happen + * @param servletName The servlet name for debug purposes + * @throws MOAIDException + * @throws IOException + */ + public static void writeCreateXMLSignatureRequestURLEncoded(HttpServletResponse resp, AuthenticationSession session, String createXMLSignatureRequestOrRedirect, String servletGoal, String servletName, String dataURL) + throws MOAIDException, + IOException { + resp.setStatus(200); + Logger.debug("ContentType set to: application/x-www-form-urlencoded"); + + resp.setContentType("application/x-www-form-urlencoded"); + + String content = "XMLRequest=" + URLEncoder.encode(createXMLSignatureRequestOrRedirect, "UTF-8") + "&" + + "DataURL=" + URLEncoder.encode(dataURL, "UTF-8"); + + OutputStream out = resp.getOutputStream(); + out.write(content.getBytes("UTF-8")); + out.flush(); + out.close(); + Logger.debug("Finished POST " + servletName); + + } +
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISMandate.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISMandate.java new file mode 100644 index 000000000..6ca059911 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISMandate.java @@ -0,0 +1,72 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.util.client.mis.simple;
+
+public class MISMandate {
+
+ final static private String OID_NOTAR = "1.2.40.0.10.3.1";
+ final static private String TEXT_NOTAR = "berufsmäßige(r) Parteienvertreter(in) mit Notariatseigenschaft";
+
+ final static private String OID_RECHTSANWALT = "1.2.40.0.10.3.2";
+ final static private String TEXT_RECHTSANWALT = "berufsmäßige(r) Parteienvertreter(in) mit Rechtsanwaltseigenschaft";
+
+ final static private String OID_ZIVILTECHNIKER = "1.2.40.0.10.3.3";
+ final static private String TEXT_ZIVILTECHNIKER = "berufsmäßige(r) Parteienvertreter(in) mit Ziviltechnikerinneneigenschaft";
+
+ final static private String OID_ORGANWALTER = "1.2.40.0.10.3.4";
+ final static private String TEXT_ORGANWALTER = "Organwalter";
+
+
+ private String oid = null;
+ private byte[] mandate = null;
+
+ public String getProfRep() {
+ return oid;
+ }
+ public void setProfRep(String oid) {
+ this.oid = oid;
+ }
+ public byte[] getMandate() {
+ return mandate;
+ }
+ public void setMandate(byte[] mandate) {
+ this.mandate = mandate;
+ }
+
+ public String getTextualDescriptionOfOID() {
+ if (this.oid.equalsIgnoreCase(OID_NOTAR))
+ return TEXT_NOTAR;
+ if (this.oid.equalsIgnoreCase(OID_RECHTSANWALT))
+ return TEXT_RECHTSANWALT;
+ if (this.oid.equalsIgnoreCase(OID_ZIVILTECHNIKER))
+ return TEXT_ZIVILTECHNIKER;
+ if (this.oid.equalsIgnoreCase(OID_ORGANWALTER))
+ return TEXT_ORGANWALTER;
+
+ return "Keine textuelle Beschreibung für OID " + oid;
+
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSessionId.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSessionId.java new file mode 100644 index 000000000..7268d0d83 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSessionId.java @@ -0,0 +1,46 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.util.client.mis.simple;
+
+public class MISSessionId {
+
+ private String sessiondId = null;
+ private String redirectURL = null;
+
+ public String getSessiondId() {
+ return sessiondId;
+ }
+ public void setSessiondId(String sessiondId) {
+ this.sessiondId = sessiondId;
+ }
+ public String getRedirectURL() {
+ return redirectURL;
+ }
+ public void setRedirectURL(String redirectURL) {
+ this.redirectURL = redirectURL;
+ }
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java new file mode 100644 index 000000000..fed9cc72b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java @@ -0,0 +1,302 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.util.client.mis.simple;
+
+import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.net.ssl.SSLSocketFactory; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.xpath.XPathAPI; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWSecureSocketFactory; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.StringUtils; +
+
+public class MISSimpleClient {
+
+
+ private final static String SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/";
+ private final static String MIS_NS = "http://reference.e-government.gv.at/namespace/mandates/mis/1.0/xsd";
+
+ private static Element NS_NODE = null;
+
+
+ static {
+ try {
+ NS_NODE = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().createElement("test");
+ NS_NODE.setAttribute("xmlns:soap", SOAP_NS);
+ NS_NODE.setAttribute("xmlns:mis", MIS_NS);
+ } catch (Exception e) {
+ Logger.warn("Error initializing namespace node.", e);
+ }
+ }
+
+ public static List sendGetMandatesRequest(String webServiceURL, String sessionId, SSLSocketFactory sSLSocketFactory) throws MISSimpleClientException {
+ if (webServiceURL == null) {
+ throw new NullPointerException("Argument webServiceURL must not be null.");
+ }
+ if (sessionId == null) {
+ throw new NullPointerException("Argument sessionId must not be null.");
+ }
+
+ // ssl settings
+ if (sSLSocketFactory != null) {
+ SZRGWSecureSocketFactory fac = new SZRGWSecureSocketFactory(sSLSocketFactory);
+ Protocol.registerProtocol("https", new Protocol("https", fac, 443));
+ }
+
+
+ try {
+ Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest");
+ Element sessionIdElement = doc.createElementNS(MIS_NS, "SessionID");
+ sessionIdElement.appendChild(doc.createTextNode(sessionId));
+ mirElement.appendChild(sessionIdElement);
+
+ // send soap request
+ Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement);
+
+ // check for error
+ checkForError(mandateIssueResponseElement);
+
+ // check for session id
+ NodeList mandateElements = XPathAPI.selectNodeList(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Mandates/mis:Mandate", NS_NODE);
+
+ if (mandateElements == null || mandateElements.getLength() == 0) {
+ throw new MISSimpleClientException("No mandates found in response.");
+ }
+
+ ArrayList foundMandates = new ArrayList();
+ for (int i=0; i<mandateElements.getLength(); i++) {
+ Element mandate = (Element) mandateElements.item(i);
+ MISMandate misMandate = new MISMandate();
+ if (mandate.hasAttribute("ProfessionalRepresentative")) {
+ misMandate.setProfRep(mandate.getAttribute("ProfessionalRepresentative"));
+ }
+
+ //misMandate.setMandate(Base64.decodeBase64(DOMUtils.getText(mandate)));
+ misMandate.setMandate(Base64.decodeBase64(DOMUtils.getText(mandate).getBytes()));
+ foundMandates.add(misMandate);
+ }
+ return foundMandates;
+ } catch (ParserConfigurationException e) {
+ throw new MISSimpleClientException(e);
+ } catch (DOMException e) {
+ throw new MISSimpleClientException(e);
+ } catch (TransformerException e) {
+ throw new MISSimpleClientException(e);
+ }
+ }
+
+ public static MISSessionId sendSessionIdRequest(String webServiceURL, byte[] idl, byte[] cert, String oaFriendlyName, String redirectURL, String referenceValue, String mandateIdentifier[], SSLSocketFactory sSLSocketFactory) throws MISSimpleClientException {
+ if (webServiceURL == null) {
+ throw new NullPointerException("Argument webServiceURL must not be null.");
+ }
+ if (idl == null) {
+ throw new NullPointerException("Argument idl must not be null.");
+ }
+ if (redirectURL == null) {
+ throw new NullPointerException("Argument redirectURL must not be null.");
+ }
+
+ // ssl settings
+ if (sSLSocketFactory != null) {
+ SZRGWSecureSocketFactory fac = new SZRGWSecureSocketFactory(sSLSocketFactory);
+ Protocol.registerProtocol("https", new Protocol("https", fac, 443));
+ }
+
+ try {
+ Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest");
+ Element idlElement = doc.createElementNS(MIS_NS, "IdentityLink");
+ + + idlElement.appendChild(doc.createTextNode(new String(Base64.encodeBase64(idl))));
+ mirElement.appendChild(idlElement);
+
+ if (cert != null && cert.length > 0) {
+ Element certElement = doc.createElementNS(MIS_NS, "X509SignatureCertificate");
+ certElement.appendChild(doc.createTextNode(new String(Base64.encodeBase64(cert))));
+ //certElement.appendChild(doc.createTextNode(Base64.encodeBase64(cert)));
+ // certElement.appendChild(doc.createTextNode(new String(Base64.encodeBase64(cert))));
+ mirElement.appendChild(certElement);
+ } + + if (!StringUtils.isEmpty(oaFriendlyName)) { + Element oaFriendlyNameElement = doc.createElementNS(MIS_NS, "OAFriendlyName"); + oaFriendlyNameElement.appendChild(doc.createTextNode(oaFriendlyName)); + mirElement.appendChild(oaFriendlyNameElement); + } +
+ Element redirectElement = doc.createElementNS(MIS_NS, "RedirectURL");
+ redirectElement.appendChild(doc.createTextNode(redirectURL));
+ mirElement.appendChild(redirectElement); + + Element referenceValueElement = doc.createElementNS(MIS_NS, "ReferenceValue"); + referenceValueElement.appendChild(doc.createTextNode(referenceValue)); + mirElement.appendChild(referenceValueElement); +
+ if (mandateIdentifier != null && mandateIdentifier.length > 0) {
+ Element filtersElement = doc.createElementNS(MIS_NS, "Filters");
+ Element mandateIdentifiersElement = doc.createElementNS(MIS_NS, "MandateIdentifiers");
+ for (int i=0; i<mandateIdentifier.length; i++) {
+ Element mandateIdentifierElement = doc.createElementNS(MIS_NS, "MandateIdentifier");
+ mandateIdentifierElement.appendChild(doc.createTextNode(mandateIdentifier[i]));
+ mandateIdentifiersElement.appendChild(mandateIdentifierElement);
+ }
+ filtersElement.appendChild(mandateIdentifiersElement);
+ mirElement.appendChild(filtersElement);
+ }
+ // send soap request
+ Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement);
+
+ // check for error
+ checkForError(mandateIssueResponseElement);
+
+ // check for session id
+ //String sessionId = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "/mis:MandateIssueResponse/mis:SessionID/text()", NS_NODE)).getNodeValue();
+ Node sessionIdNode = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:SessionID/text()", NS_NODE));
+ if (sessionIdNode == null) {
+ throw new MISSimpleClientException("SessionId not found in response.");
+ }
+ String sessionId = sessionIdNode.getNodeValue();
+
+ Node guiRedirectURLNode = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:GuiRedirectURL/text()", NS_NODE));
+ if (guiRedirectURLNode == null) {
+ throw new MISSimpleClientException("GuiRedirectURL not found in response.");
+ }
+ String guiRedirectURL = guiRedirectURLNode.getNodeValue();
+
+ // create return object
+ MISSessionId msid = new MISSessionId();
+ msid.setSessiondId(sessionId);
+ msid.setRedirectURL(guiRedirectURL);
+
+ return msid;
+ } catch (ParserConfigurationException e) {
+ throw new MISSimpleClientException(e);
+ } catch (DOMException e) {
+ throw new MISSimpleClientException(e);
+ } catch (TransformerException e) {
+ throw new MISSimpleClientException(e);
+ }
+
+ }
+
+ private static void checkForError(Element mandateIssueResponseElement) throws MISSimpleClientException {
+ if (mandateIssueResponseElement == null) {
+ throw new NullPointerException("Argument mandateIssueResponseElement must not be null.");
+ }
+ try {
+ Element errorElement = (Element) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Error", NS_NODE);
+ if (errorElement != null) {
+ String code = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Error/mis:Code/text()", NS_NODE)).getNodeValue();
+ String text = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Error/mis:Text/text()", NS_NODE)).getNodeValue();
+ throw new MISSimpleClientException("Fehler beim Abfragen des Online-Vollmachten Services: " + code + " / " + text); }
+ } catch (TransformerException e) {
+ throw new MISSimpleClientException(e);
+ }
+ }
+
+ private static Element sendSOAPRequest(String webServiceURL, Element request) throws MISSimpleClientException { + +// try { +// System.out.println("REQUEST-MIS: \n" + DOMUtils.serializeNode(request)); +// } catch (TransformerException e1) { +// e1.printStackTrace(); +// } catch (IOException e1) { +// e1.printStackTrace(); +// } +
+ if (webServiceURL == null) {
+ throw new NullPointerException("Argument webServiceURL must not be null.");
+ }
+ if (request == null) {
+ throw new NullPointerException("Argument request must not be null.");
+ }
+ try {
+ HttpClient httpclient = new HttpClient();
+ PostMethod post = new PostMethod(webServiceURL);
+ StringRequestEntity re = new StringRequestEntity(DOMUtils.serializeNode(packIntoSOAP(request)),"text/xml", "UTF-8");
+ post.setRequestEntity(re);
+ int responseCode = httpclient.executeMethod(post); +
+ if (responseCode != 200) {
+ throw new MISSimpleClientException("Invalid HTTP response code " + responseCode);
+ }
+ //Element elem = parse(post.getResponseBodyAsStream());
+ Document doc = DOMUtils.parseDocumentSimple(post.getResponseBodyAsStream());
+ return unpackFromSOAP(doc.getDocumentElement());
+ } catch(IOException e) {
+ throw new MISSimpleClientException(e);
+ } catch (TransformerException e) {
+ throw new MISSimpleClientException(e);
+ } catch (SAXException e) {
+ throw new MISSimpleClientException(e);
+ } catch (ParserConfigurationException e) {
+ throw new MISSimpleClientException(e);
+ }
+ }
+
+ private static Element packIntoSOAP(Element element) throws MISSimpleClientException {
+ try {
+ Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ Element soapEnvelope = doc.createElement("Envelope");
+ soapEnvelope.setAttribute("xmlns", SOAP_NS);
+ Element soapBody = doc.createElement("Body");
+ soapEnvelope.appendChild(soapBody);
+ soapBody.appendChild(doc.importNode(element, true));
+ return soapEnvelope;
+ } catch(ParserConfigurationException e) {
+ throw new MISSimpleClientException(e);
+ }
+ }
+
+ private static Element unpackFromSOAP(Element element) throws MISSimpleClientException {
+ try {
+ return (Element) XPathAPI.selectSingleNode(element, "/soap:Envelope/soap:Body/child::*[position()=1]", NS_NODE);
+ } catch(TransformerException e) {
+ throw new MISSimpleClientException(e);
+ }
+ }
+}
\ No newline at end of file diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClientException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClientException.java new file mode 100644 index 000000000..81251139a --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClientException.java @@ -0,0 +1,46 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.util.client.mis.simple;
+
+public class MISSimpleClientException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public MISSimpleClientException() {
+ }
+
+ public MISSimpleClientException(String message) {
+ super(message);
+ }
+
+ public MISSimpleClientException(Throwable cause) {
+ super(cause);
+ }
+
+ public MISSimpleClientException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
\ No newline at end of file |