WebObjects HTTPS – SSLv3 Poodle vulnerability
WebObjects HTTPS – SSLv3 Poodle vulnerability
- Subject: WebObjects HTTPS – SSLv3 Poodle vulnerability
- From: Helmut Tschemernjak <email@hidden>
- Date: Fri, 19 Dec 2014 16:08:20 +0100
- Organization: HELIOS Software GmbH
Dear all,
I believe only a very few of you deploying WebObjects solutions with
direct connect https, without the Apache adapter. If the WebObjects
direct connect WOSSLAdaptor is used to support https connections, in
this case WebObjects is SSLv3 Poodle vulnerability.
We fixed this in our solution by creating a own https connection setup
via our new "WSSSLAdaptor.java" class which I like to make available to
everyone, the source is attached. We basically re-initialize the https
network socket and and set the proper enabled socket via reflection in
the WOClassicAdaptor. We also added UTF-8 support for the password.
For our products we did a Tech Info which basically describes the problem.
http://www.helios.de/web/EN/support/TI/167.html
Merry Christmas & Happy New Year 2015
Helmut
/*
* $Id: WSSSLAdaptor.java,v 1.1.2.3 2014/12/11 14:47:39 $
*/
package de.helios.webshare.net;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.URL;
import java.security.KeyStore;
import java.util.HashSet;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import com.webobjects.appserver.WOApplication;
import com.webobjects.appserver._private.WOClassicAdaptor;
import com.webobjects.foundation.NSBundle;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSForwardException;
import com.webobjects.foundation.NSLog;
public class WSSSLAdaptor extends WOClassicAdaptor {
/*
* enable ssl debugging via:
* -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl
*/
@SuppressWarnings("rawtypes")
public WSSSLAdaptor(String aName, NSDictionary anAdaptorArgsDict) {
/*
* Override of private methods is not possible_
* Create a regular http adapter first via WOClassicAdaptor
* later we replace the http socket with our https version.
*/
super(aName, anAdaptorArgsDict);
initSSLProtocols();
}
protected void initSSLProtocols() {
try {
/* use reflection to get access to private member var _listenSocket */
Class<?> c = Class.forName("com.webobjects.appserver._private.WOClassicAdaptor");
Field f_listenSocket;
f_listenSocket = c.getDeclaredField("_listenSocket");
f_listenSocket.setAccessible(true);
ServerSocket listenSocket = (ServerSocket) f_listenSocket.get(this);
if (listenSocket != null) {
try {
listenSocket.setReuseAddress(true);
listenSocket.close();
} catch(IOException io) {}
}
Field f_listenQueueSize;
f_listenQueueSize = c.getDeclaredField("_listenQueueSize");
f_listenQueueSize.setAccessible(true);
int listenQueueSize = f_listenQueueSize.getInt(this);
Field f_host;
f_host = c.getDeclaredField("_host");
f_host.setAccessible(true);
InetAddress host = (InetAddress) f_host.get(this);
String keystore = "adaptorssl.key";
char[] sllpassphrase = getSSLPassphrase();
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(WOApplication.application().createResourceManager().inputStreamForResourceNamed(keystore, null, null), sllpassphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, sllpassphrase);
SSLContext sslcontext = SSLContext.getInstance("SSLv3");
sslcontext.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = sslcontext.getServerSocketFactory();
SSLServerSocket sslSocket;
if (WOApplication.application()._unsetHost)
sslSocket = (SSLServerSocket) ssf.createServerSocket(_port, listenQueueSize);
else
sslSocket = (SSLServerSocket) ssf.createServerSocket(_port, listenQueueSize, host);
HashSet<String> disabledProtocolls = getDisabledProtocolls();
/*
* Fix SSL V3.0 "Poodle" Vulnerability
* http://www.oracle.com/technetwork
* /java/javase/documentation/cve-2014-3566-2342133.html
*/
String[] protocols = sslSocket.getEnabledProtocols();
HashSet<String> set = new HashSet<String>();
for (String s : protocols) {
if (disabledProtocolls.contains(s)) {
continue;
}
set.add(s);
}
sslSocket.setEnabledProtocols(set.toArray(new String[0]));
/* set _listenSocket */
f_listenSocket.set(this, sslSocket);
} catch (Exception e) {
NSLog.err.appendln("Unable to establish an SSL connection to port "
+ _port
+ " on this host. Perhaps this port is already in use by another WebObjects application instance.");
throw NSForwardException._runtimeExceptionForThrowable(e);
}
}
protected HashSet<String> getDisabledProtocolls() {
HashSet<String> disabledProts = new HashSet<String>();
String prop = System.getProperty("WSDisabledSSLProtocols");
if (prop == null) {
prop = "SSLv3,SSLv2Hello";
}
if (prop != null) {
String[] list = prop.split(",");
for(String protocol : list) {
disabledProts.add(protocol.trim());
}
}
return disabledProts;
}
/* support of UTF-8 passphares */
protected char[] getSSLPassphrase() {
char[] pphrase = {};
try {
String resourcePath = NSBundle.mainBundle()
.resourcePathForLocalizedResourceNamed(
"adaptorsslpassphrase", null);
URL pathURL = NSBundle.mainBundle().pathURLForResourcePath(
resourcePath);
String path = pathURL != null ? (path = pathURL.getPath()) : null;
if (path != null) {
Process proc = Runtime.getRuntime().exec(path);
InputStream ios = proc.getInputStream();
proc.waitFor();
ByteArrayOutputStream ba = new ByteArrayOutputStream();
int b;
while( (b = ios.read()) != -1) {
ba.write(b);
}
byte[] pp = ba.toByteArray();
String tmp = new String(pp, "UTF-8").trim();
pp = tmp.getBytes("UTF-8");
char[] ca = new char[pp.length];
for(int i = 0; i < pp.length; i++) {
ca[i] = (char)(pp[i] & 255);
}
pphrase = ca;
}
} catch (Exception ex) {
NSLog.err.appendln("Unable to read ssl passphrase.");
}
return pphrase;
}
@Override
public synchronized void registerForEvents() {
registerForEvents(true);
}
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden