import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.List;
+
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+
import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageReadWrite;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.factory.BasicFactory;
.getLogger(SecureMessageReadWriteService.class);
private Selector selector;
- private SelectionKey clientSelectionKey;
private SocketChannel socket;
private BasicFactory factory;
createSecureChannel(socket);
createBuffers(sslEngine);
} catch (Exception e) {
+ logger.warn("Failed to setup TLS connection {} {}", socket, e);
stop();
throw e;
}
/**
* Bring up secure channel using SSL Engine
- *
+ *
* @param socket
* TCP socket channel
* @throws Exception
keyStoreFile = keyStoreFile.trim();
}
if ((keyStoreFile == null) || keyStoreFile.isEmpty()) {
- throw new FileNotFoundException(
- "controllerKeyStore not specified in ./configuration/config.ini");
+ throw new FileNotFoundException("TLS KeyStore file not found.");
}
if (keyStorePassword != null) {
keyStorePassword = keyStorePassword.trim();
}
if ((keyStorePassword == null) || keyStorePassword.isEmpty()) {
- throw new FileNotFoundException(
- "controllerKeyStorePassword not specified in ./configuration/config.ini");
+ throw new FileNotFoundException("TLS KeyStore Password not provided.");
}
if (trustStoreFile != null) {
trustStoreFile = trustStoreFile.trim();
}
if ((trustStoreFile == null) || trustStoreFile.isEmpty()) {
- throw new FileNotFoundException(
- "controllerTrustStore not specified in ./configuration/config.ini");
+ throw new FileNotFoundException("TLS TrustStore file not found");
}
if (trustStorePassword != null) {
trustStorePassword = trustStorePassword.trim();
}
if ((trustStorePassword == null) || trustStorePassword.isEmpty()) {
- throw new FileNotFoundException(
- "controllerTrustStorePassword not specified in ./configuration/config.ini");
+ throw new FileNotFoundException("TLS TrustStore Password not provided.");
}
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
- KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
- TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kfd = new FileInputStream(keyStoreFile);
tfd = new FileInputStream(trustStoreFile);
ks.load(kfd, keyStorePassword.toCharArray());
sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(true);
+ sslEngine.setEnabledCipherSuites(new String[] {
+ "SSL_RSA_WITH_RC4_128_MD5",
+ "SSL_RSA_WITH_RC4_128_SHA",
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
+ "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+ "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"});
// Do initial handshake
doHandshake(socket, sslEngine);
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ);
+ this.socket.register(this.selector, SelectionKey.OP_READ);
}
/**
* Sends the OF message out over the socket channel. The message is
* encrypted by SSL Engine.
- *
+ *
* @param msg
* OF message to be sent
* @throws Exception
if (myAppData.hasRemaining()) {
myAppData.compact();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_WRITE, this);
+ this.socket.register(this.selector, SelectionKey.OP_WRITE, this);
} else {
myAppData.clear();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
+ this.socket.register(this.selector, SelectionKey.OP_READ, this);
}
logger.trace("Message sent: {}", msg);
/**
* Resumes sending the remaining messages in the outgoing buffer
- *
+ *
* @throws Exception
*/
@Override
if (myAppData.hasRemaining()) {
myAppData.compact();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_WRITE, this);
+ this.socket.register(this.selector, SelectionKey.OP_WRITE, this);
} else {
myAppData.clear();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
+ this.socket.register(this.selector, SelectionKey.OP_READ, this);
}
}
}
/**
* Reads the incoming network data from the socket, decryptes them and then
* retrieves the OF messages.
- *
+ *
* @return list of OF messages
* @throws Exception
*/
peerNetData.position(), peerNetData.limit());
}
- peerAppData.flip();
- msgs = factory.parseMessages(peerAppData);
- if (peerAppData.hasRemaining()) {
- peerAppData.compact();
- } else {
+ try {
+ peerAppData.flip();
+ msgs = factory.parseMessages(peerAppData);
+ if (peerAppData.hasRemaining()) {
+ peerAppData.compact();
+ } else {
+ peerAppData.clear();
+ }
+ } catch (Exception e) {
peerAppData.clear();
+ logger.debug("Caught exception: ", e);
}
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
+ this.socket.register(this.selector, SelectionKey.OP_READ, this);
return msgs;
}
this.myAppData = ByteBuffer
.allocate(session.getApplicationBufferSize());
this.peerAppData = ByteBuffer.allocate(session
- .getApplicationBufferSize());
+ .getApplicationBufferSize() * 2);
this.myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
- this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
+ this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize() * 2);
}
@Override