Hi
I'm trying to implement aprt of a RADIUS server (EAP/TLS)f my master thesis. I'm not used to Java SSL libraries and can't get it to work. The server will respond to an accesspoint that uses 802.1x. I have created certificates using openssl and imported the "cert-clt.pl2"and "root.pem" to a laptop trying to connect to the accesspoint. On the server side i imported the "cacert.pem" and "cert-srv.der" using keytool to a keystore. In my code I read the keystore and create the SSLEngine with following code:
KeyStore ksKeys = KeyStore.getInstance("JKS");
ksKeys.load(new FileInputStream("certs/FeebeeCommunity.keystore"), passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ksKeys, passphrase);
/*
KeyStore ksTrust = KeyStore.getInstance("JKS");
ksTrust.load(new FileInputStream("FeebeeCommunity.keystore"), passphrase);
*/
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ksKeys);
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(true);
sslEngine.setWantClientAuth(true);
sslEngine.setEnableSessionCreation(true);
appBuffer = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
appBuffer.clear();
netBuffer = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
netBuffer.clear();
All I want to do with TLS is a handshake.
I'm not talking ssl using sockets instead I receive and send all TLS data encapsulated in EAP packet that are incapsulated in RADIUS packets. I start off with sending TLS-Start upon I recive TLS data. I handle it with the following code:
SSLEngineResult result = null;
SSLEngineResult.HandshakeStatus hsStatus = null;
if( internalState != EAPTLSState.Handshaking ) {
if( internalState == EAPTLSState.None ) {
TLSPacket tlsPacket = new TLSPacket( packet.getData() );
peerIdentity = tlsPacket.getData();
internalState = EAPTLSState.Starting;
try {
sslEngine.beginHandshake();
} catch (SSLException e) {
e.printStackTrace();
}
return;
}
else if(internalState == EAPTLSState.Starting ) {
internalState = EAPTLSState.Handshaking;
try {
sslEngine.beginHandshake();
} catch (SSLException e) {
e.printStackTrace();
}
}
}
TLSPacket tlsPacket = new TLSPacket( packet.getData() );
netBuffer.put( tlsPacket.getData() );
netBuffer.flip();
while(true) {
hsStatus = sslEngine.getHandshakeStatus();
if(hsStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) {
Runnable task;
while((task=sslEngine.getDelegatedTask()) != null) {
new Thread(task).start();
}
}
else if(hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
try {
result = sslEngine.unwrap( netBuffer, appBuffer );
} catch (SSLException e) {
e.printStackTrace();
}
}
else {
return;
}
}
When I try to send data I use the following code:
SSLEngineResult.HandshakeStatus hsStatus = null;
SSLEngineResult result = null;
// netBuffer = ByteBuffer.allocate(EAPTLSMethod.BUFFER_SIZE);
netBuffer.clear();
while(true) {
hsStatus = sslEngine.getHandshakeStatus();
if(hsStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) {
Runnable task;
while((task=sslEngine.getDelegatedTask()) != null) {
new Thread(task).start();
}
}
else if(hsStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
try {
result = sslEngine.wrap( dummyBuffer, netBuffer );
} catch (SSLException e) {
e.printStackTrace();
}
}
else {
if( result != null && result.getStatus() == SSLEngineResult.Status.OK ) {
int size = Math.min(result.bytesProduced(),this.MTU);
byte [] tlsData = new byte[size];
netBuffer.flip();
netBuffer.get(tlsData,0,size);
TLSPacket tlsPacket = new TLSPacket((byte)0,tlsData);
if( size < result.bytesProduced() ) {
tlsPacket.setFlag(TLSFlag.MoreFragments);
}
return new EAPTLSRequestPacket( ID,
(short)(tlsPacket.getData().length + 6),
stateMachine.getCurrentMethod(), tlsPacket );
}
else {
return null;
}
}
After I sent TLS-Start I receive data and manage to process it but when then trying to produce TLS data I get the following error:
javax.net.ssl.SSLHandshakeException: no cipher suites in common
at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Handshaker.java:992)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:459)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1054)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1026)
at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:411)
at RadiusServerSimulator.EAPModule.EAPTLSMethod.buildReq(EAPTLSMethod.java:125)
at RadiusServerSimulator.EAPModule.EAPStateMachine.methodRequest(EAPStateMachine.java:358)
at RadiusServerSimulator.EAPModule.EAPStateMachine.run(EAPStateMachine.java:262)
at java.lang.Thread.run(Thread.java:595)
Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:176)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:164)
at com.sun.net.ssl.internal.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:638)
at com.sun.net.ssl.internal.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:450)
at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:178)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Handshaker.java:437)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Handshaker.java:930)
Any help wold be most greatfull, if any questions or anything unclear plz let me know.