diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 8b2a449f..6811fc72 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -1,13 +1,15 @@
OpenAS2 Server
- Version 1.2.0
+ Version 1.3.0
RELEASE NOTES
-The OpenAS2 project is pleased to announce the release of OpenAS2 1.2.0
+The OpenAS2 project is pleased to announce the release of OpenAS2 1.3.0
-The release download file is: OpenAS2Server-1.2.0.zip
+The release download file is: OpenAS2Server-1.3.0.zip
The zip file contains a PDF document providing information on installing and using the application.
-This release adds support for compression and decompression of AS2 messages per RFC5042.
+This release adds support for:
+ - using HTTPS as the transport protocol.
+ - overriding the the password for the certificate store with a system parameter passed into the app at startup
Java 1.5 or later is required.
diff --git a/Server/bin/start-openas2.sh b/Server/bin/start-openas2.sh
index 055f2874..0bd71557 100755
--- a/Server/bin/start-openas2.sh
+++ b/Server/bin/start-openas2.sh
@@ -1,5 +1,12 @@
#!/bin/sh
# purpose: runs the OpenAS2 application
+x=`basename $0`
+
+keyStorePwd=$1
+PWD_OVERRIDE=""
+if [ ! -z $keyStorePwd ]; then
+ PWD_OVERRIDE="-Dorg.openas2.cert.Password=$keyStorePwd"
+fi
if [ -z $JAVA_HOME ]; then
OS=$(uname -s)
@@ -23,4 +30,4 @@ JAVA_EXE=$JAVA_HOME/bin/java
#
# remove -Dorg.apache.commons.logging.Log=org.openas2.logging.Log if using another logging package
#
-$JAVA_EXE -Xms32m -Xmx384m -Dorg.apache.commons.logging.Log=org.openas2.logging.Log -cp .:../lib/javax.mail.jar:../lib/bcpkix-jdk15on-152.jar:../lib/bcprov-jdk15on-152.jar:../lib/bcmail-jdk15on-152.jar:../lib/bcprov-jdk15on-152:../lib/commons-logging-1.2.jar:../lib/openas2-server.jar org.openas2.app.OpenAS2Server ../config/config.xml
+$JAVA_EXE ${PWD_OVERRIDE} -Xms32m -Xmx384m -Dorg.apache.commons.logging.Log=org.openas2.logging.Log -cp .:../lib/javax.mail.jar:../lib/bcpkix-jdk15on-152.jar:../lib/bcprov-jdk15on-152.jar:../lib/bcmail-jdk15on-152.jar:../lib/bcprov-jdk15on-152:../lib/commons-logging-1.2.jar:../lib/openas2-server.jar org.openas2.app.OpenAS2Server ../config/config.xml
diff --git a/Server/config/config.xml b/Server/config/config.xml
index 23ab0f33..314eedb6 100644
--- a/Server/config/config.xml
+++ b/Server/config/config.xml
@@ -90,10 +90,29 @@
port="10080"
errordir="%home%/../data/inbox/error"
errorformat="sender.as2_id, receiver.as2_id, headers.message-id"/>
-
+
+
+
options) throws OpenAS2Exception {
super.init(session, options);
-
+
+ // Override the password if it was passed as a system property
+ String pwd = System.getProperty("org.openas2.cert.Password");
+ if (pwd != null)
+ {
+ setPassword(pwd.toCharArray());
+ }
try {
this.keyStore = AS2Util.getCryptoHelper().getKeyStore();
} catch (Exception e) {
diff --git a/Server/src/org/openas2/processor/receiver/AS2ReceiverHandler.java b/Server/src/org/openas2/processor/receiver/AS2ReceiverHandler.java
index 7d1ab9f3..26e8ce82 100644
--- a/Server/src/org/openas2/processor/receiver/AS2ReceiverHandler.java
+++ b/Server/src/org/openas2/processor/receiver/AS2ReceiverHandler.java
@@ -75,6 +75,7 @@ public void handle(NetModule owner, Socket s) {
} catch (Exception e) {
+ logger.error("HTTP connection error on inbound message.", e);
NetException ne = new NetException(s.getInetAddress(), s.getPort(), e);
ne.terminate();
}
diff --git a/Server/src/org/openas2/processor/receiver/NetModule.java b/Server/src/org/openas2/processor/receiver/NetModule.java
index b1b5e28d..b9f65c46 100644
--- a/Server/src/org/openas2/processor/receiver/NetModule.java
+++ b/Server/src/org/openas2/processor/receiver/NetModule.java
@@ -1,13 +1,28 @@
package org.openas2.processor.receiver;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
import java.util.Map;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.openas2.OpenAS2Exception;
import org.openas2.Session;
import org.openas2.WrappedException;
@@ -15,25 +30,33 @@
import org.openas2.message.Message;
import org.openas2.params.CompositeParameters;
import org.openas2.params.DateParameters;
+import org.openas2.params.InvalidParameterException;
import org.openas2.params.MessageParameters;
+import org.openas2.processor.sender.AS2SenderModule;
import org.openas2.util.IOUtilOld;
public abstract class NetModule extends BaseReceiverModule {
public static final String PARAM_ADDRESS = "address";
public static final String PARAM_PORT = "port";
+ public static final String PARAM_PROTOCOL = "protocol";
+ public static final String PARAM_SSL_KEYSTORE = "ssl_keystore";
+ public static final String PARAM_SSL_KEYSTORE_PASSWORD = "ssl_keystore_password";
+ public static final String PARAM_SSL_PROTOCOL = "ssl_protocol";
public static final String PARAM_ERROR_DIRECTORY = "errordir";
public static final String PARAM_ERRORS = "errors";
public static final String DEFAULT_ERRORS = "$date.yyyyMMddhhmmss$";
- private MainThread mainThread;
+ private HTTPServerThread mainThread;
+ private Log logger = LogFactory.getLog(AS2SenderModule.class.getSimpleName());
public void doStart() throws OpenAS2Exception {
try {
- mainThread = new MainThread(this, getParameter(PARAM_ADDRESS, false),
+ mainThread = new HTTPServerThread(this, getParameter(PARAM_ADDRESS, false),
getParameterInt(PARAM_PORT, true));
mainThread.start();
} catch (IOException ioe) {
+ logger.error("Error in HTTP connection.", ioe);
throw new WrappedException(ioe);
}
}
@@ -48,6 +71,13 @@ public void doStop() throws OpenAS2Exception {
public void init(Session session, Map options) throws OpenAS2Exception {
super.init(session, options);
getParameter(PARAM_PORT, true);
+ // Override the password if it was passed as a system property
+ String pwd = System.getProperty("org.openas2.ssl.Password");
+ if (pwd != null)
+ {
+ setParameter(PARAM_SSL_KEYSTORE_PASSWORD, pwd);;
+ }
+
}
protected abstract NetModuleHandler getHandler();
@@ -122,22 +152,119 @@ public void run() {
}
}
- protected class MainThread extends Thread {
+ protected class HTTPServerThread extends Thread {
private NetModule owner;
private ServerSocket socket;
private boolean terminated;
- public MainThread(NetModule owner, String address, int port)
+ public HTTPServerThread(NetModule owner, String address, int port)
throws IOException {
super();
this.owner = owner;
-
- socket = new ServerSocket();
-
- if (address != null) {
- socket.bind(new InetSocketAddress(address, port));
- } else {
- socket.bind(new InetSocketAddress(port));
+ String protocol = "http";
+ String sslProtocol = "TLS";
+ try
+ {
+ protocol = owner.getParameter(PARAM_PROTOCOL, "http");
+ sslProtocol = owner.getParameter(PARAM_SSL_PROTOCOL, "TLS");
+ } catch (InvalidParameterException e)
+ {
+ // Do nothing
+ }
+ if ("https".equalsIgnoreCase(protocol))
+ {
+ String ksName;
+ char [] ksPass;
+ try
+ {
+ ksName = owner.getParameter(PARAM_SSL_KEYSTORE, true);
+ ksPass = owner.getParameter(PARAM_SSL_KEYSTORE_PASSWORD, true).toCharArray();
+ } catch (InvalidParameterException e)
+ {
+ logger.error("Required SSL parameter missing.", e);
+ throw new IOException("Failed to retireve require SSL parameters. Check config XML");
+ }
+ KeyStore ks;
+ try
+ {
+ ks = KeyStore.getInstance("JKS");
+ } catch (KeyStoreException e)
+ {
+ logger.error("Failed to initialise SSL keystore.", e);
+ throw new IOException("Error initialising SSL keystore");
+ }
+ try
+ {
+ ks.load(new FileInputStream(ksName), ksPass);
+ } catch (NoSuchAlgorithmException e)
+ {
+ logger.error("Failed to load keystore: " + ksName, e);
+ throw new IOException("Error loading SSL keystore");
+ } catch (CertificateException e)
+ {
+ logger.error("Failed to load SSL certificate: " + ksName, e);
+ throw new IOException("Error loading SSL certificate");
+ }
+ KeyManagerFactory kmf;
+ try
+ {
+ kmf = KeyManagerFactory.getInstance("SunX509");
+ } catch (NoSuchAlgorithmException e)
+ {
+ logger.error("Failed to create key manager instance", e);
+ throw new IOException("Error creating SSL key manager instance");
+ }
+ try
+ {
+ kmf.init(ks, ksPass);
+ } catch (Exception e)
+ {
+ logger.error("Failed to initialise key manager instance", e);
+ throw new IOException("Error initialising SSL key manager instance");
+ }
+ // setup the trust manager factory
+ TrustManagerFactory tmf;
+ try
+ {
+ tmf = TrustManagerFactory.getInstance ( "SunX509" );
+ tmf.init( ks );
+ } catch (Exception e1)
+ {
+ logger.error("Failed to create trust manager instance", e1);
+ throw new IOException("Error creating SSL trust manager instance");
+ }
+ SSLContext sc;
+ try
+ {
+ sc = SSLContext.getInstance(sslProtocol);
+ } catch (NoSuchAlgorithmException e)
+ {
+ logger.error("Failed to create SSL context instance", e);
+ throw new IOException("Error creating SSL context instance");
+ }
+ try
+ {
+ sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ } catch (KeyManagementException e)
+ {
+ logger.error("Failed to initialise SSL context instance", e);
+ throw new IOException("Error initialising SSL context instance");
+ }
+ SSLServerSocketFactory ssf = sc.getServerSocketFactory();
+ if (address != null) {
+ socket = (SSLServerSocket) ssf.createServerSocket(port, 0, InetAddress.getByName(address));
+ }
+ else
+ socket = (SSLServerSocket) ssf.createServerSocket(port);
+ }
+ else
+ {
+ socket = new ServerSocket();
+ if (address != null) {
+ socket.bind(new InetSocketAddress(address, port));
+ } else {
+ socket.bind(new InetSocketAddress(port));
+ }
}
}
diff --git a/Server/src/org/openas2/processor/sender/AS2SenderModule.java b/Server/src/org/openas2/processor/sender/AS2SenderModule.java
index 9c2efb90..b9075292 100644
--- a/Server/src/org/openas2/processor/sender/AS2SenderModule.java
+++ b/Server/src/org/openas2/processor/sender/AS2SenderModule.java
@@ -79,6 +79,7 @@ public void handle(String action, Message msg, Map