Add DTLS 1.3 SSLEngine example client and server applications
Co-Authored-By: chris@wolfssl.com <chris@wolfssl.com>devin/1741390781-dtls13-examples
parent
ad23ac20e9
commit
7189b086fe
|
@ -0,0 +1,271 @@
|
||||||
|
/* SSLEngineClientDTLS13.java
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfSSL.
|
||||||
|
*
|
||||||
|
* wolfSSL is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfSSL is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example DTLS 1.3 client using SSLEngine.
|
||||||
|
*
|
||||||
|
* This client connects to a DTLS 1.3 server, sends data, receives a response,
|
||||||
|
* and then shuts down the connection. This example is compiled when
|
||||||
|
* 'ant examples' is run in the package root.
|
||||||
|
*
|
||||||
|
* $ ant examples
|
||||||
|
* $ ./examples/provider/SSLEngineClientDTLS13.sh
|
||||||
|
*
|
||||||
|
* For testing, start the SSLEngineServerDTLS13 example first:
|
||||||
|
*
|
||||||
|
* $ ./examples/provider/SSLEngineServerDTLS13.sh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.nio.channels.*;
|
||||||
|
import javax.net.ssl.*;
|
||||||
|
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
||||||
|
import java.security.*;
|
||||||
|
import com.wolfssl.provider.jsse.WolfSSLProvider;
|
||||||
|
|
||||||
|
public class SSLEngineClientDTLS13 {
|
||||||
|
/* Keystore and connection settings */
|
||||||
|
private char[] psw;
|
||||||
|
private String clientKS = "./examples/provider/client.jks";
|
||||||
|
private String caKS = "./examples/provider/ca-server.jks";
|
||||||
|
private String jsseProv = "wolfJSSE";
|
||||||
|
private String host = "localhost";
|
||||||
|
private int port = 11119;
|
||||||
|
|
||||||
|
/* Initialize password from environment or system property */
|
||||||
|
{
|
||||||
|
String password = System.getProperty("javax.net.ssl.keyStorePassword");
|
||||||
|
if (password == null) {
|
||||||
|
password = System.getenv("WOLFSSL_PASSWORD");
|
||||||
|
}
|
||||||
|
if (password == null) {
|
||||||
|
System.err.println("Warning: Using empty password. Set password with " +
|
||||||
|
"javax.net.ssl.keyStorePassword property or WOLFSSL_PASSWORD env var");
|
||||||
|
password = "";
|
||||||
|
}
|
||||||
|
psw = password.toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSLEngineClientDTLS13() {
|
||||||
|
try {
|
||||||
|
Security.addProvider(new WolfSSLProvider());
|
||||||
|
|
||||||
|
/* Set up KeyStore */
|
||||||
|
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
|
||||||
|
clientKeyStore.load(new FileInputStream(clientKS), psw);
|
||||||
|
|
||||||
|
KeyManagerFactory km = KeyManagerFactory
|
||||||
|
.getInstance("SunX509", jsseProv);
|
||||||
|
km.init(clientKeyStore, psw);
|
||||||
|
|
||||||
|
/* Set up CA TrustManagerFactory */
|
||||||
|
KeyStore caKeyStore = KeyStore.getInstance("JKS");
|
||||||
|
caKeyStore.load(new FileInputStream(caKS), psw);
|
||||||
|
|
||||||
|
TrustManagerFactory tm = TrustManagerFactory
|
||||||
|
.getInstance("SunX509", jsseProv);
|
||||||
|
tm.init(caKeyStore);
|
||||||
|
|
||||||
|
/* Create SSLContext for DTLS 1.3 */
|
||||||
|
SSLContext ctx = SSLContext.getInstance("DTLSv1.3", jsseProv);
|
||||||
|
ctx.init(km.getKeyManagers(), tm.getTrustManagers(), null);
|
||||||
|
|
||||||
|
/* Create DatagramSocket for DTLS */
|
||||||
|
DatagramSocket clientSocket = new DatagramSocket();
|
||||||
|
InetAddress serverAddress = InetAddress.getByName(host);
|
||||||
|
|
||||||
|
/* Create SSLEngine */
|
||||||
|
SSLEngine engine = ctx.createSSLEngine(host, port);
|
||||||
|
engine.setUseClientMode(true);
|
||||||
|
|
||||||
|
/* Configure SSLEngine for DTLS */
|
||||||
|
SSLSession session = engine.getSession();
|
||||||
|
int appBufferSize = session.getApplicationBufferSize();
|
||||||
|
int netBufferSize = session.getPacketBufferSize();
|
||||||
|
|
||||||
|
/* Start handshake */
|
||||||
|
engine.beginHandshake();
|
||||||
|
|
||||||
|
/* Connect to server, perform handshake, send/receive data */
|
||||||
|
connectToServer(engine, clientSocket, serverAddress, port);
|
||||||
|
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void connectToServer(SSLEngine engine, DatagramSocket socket,
|
||||||
|
InetAddress serverAddress, int serverPort) {
|
||||||
|
try {
|
||||||
|
SSLSession session = engine.getSession();
|
||||||
|
ByteBuffer appData = ByteBuffer.allocate(session.getApplicationBufferSize());
|
||||||
|
ByteBuffer netData = ByteBuffer.allocate(session.getPacketBufferSize());
|
||||||
|
ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
|
||||||
|
ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
|
||||||
|
|
||||||
|
HandshakeStatus status = engine.getHandshakeStatus();
|
||||||
|
boolean handshakeComplete = false;
|
||||||
|
|
||||||
|
/* Handle handshake */
|
||||||
|
while (!handshakeComplete) {
|
||||||
|
switch (status) {
|
||||||
|
case NEED_WRAP:
|
||||||
|
/* Wrap handshake data */
|
||||||
|
netData.clear();
|
||||||
|
SSLEngineResult wrapResult = engine.wrap(appData, netData);
|
||||||
|
status = wrapResult.getHandshakeStatus();
|
||||||
|
|
||||||
|
/* Send wrapped data to server */
|
||||||
|
netData.flip();
|
||||||
|
byte[] data = new byte[netData.remaining()];
|
||||||
|
netData.get(data);
|
||||||
|
DatagramPacket sendPacket = new DatagramPacket(
|
||||||
|
data, data.length, serverAddress, serverPort);
|
||||||
|
socket.send(sendPacket);
|
||||||
|
|
||||||
|
/* Handle tasks */
|
||||||
|
if (status == HandshakeStatus.NEED_TASK) {
|
||||||
|
Runnable task;
|
||||||
|
while ((task = engine.getDelegatedTask()) != null) {
|
||||||
|
task.run();
|
||||||
|
}
|
||||||
|
status = engine.getHandshakeStatus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NEED_UNWRAP:
|
||||||
|
/* Receive data from server */
|
||||||
|
peerNetData.clear();
|
||||||
|
DatagramPacket packet = new DatagramPacket(
|
||||||
|
peerNetData.array(), peerNetData.capacity());
|
||||||
|
socket.receive(packet);
|
||||||
|
peerNetData.position(packet.getLength());
|
||||||
|
peerNetData.flip();
|
||||||
|
|
||||||
|
/* Unwrap received data */
|
||||||
|
SSLEngineResult result = engine.unwrap(peerNetData, peerAppData);
|
||||||
|
peerNetData.compact();
|
||||||
|
status = result.getHandshakeStatus();
|
||||||
|
|
||||||
|
/* Handle tasks */
|
||||||
|
if (status == HandshakeStatus.NEED_TASK) {
|
||||||
|
Runnable task;
|
||||||
|
while ((task = engine.getDelegatedTask()) != null) {
|
||||||
|
task.run();
|
||||||
|
}
|
||||||
|
status = engine.getHandshakeStatus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FINISHED:
|
||||||
|
handshakeComplete = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NOT_HANDSHAKING:
|
||||||
|
handshakeComplete = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Invalid handshake status: " + status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handshake complete, now send application data */
|
||||||
|
System.out.println("Handshake completed, sending data to server");
|
||||||
|
|
||||||
|
/* Prepare message to send */
|
||||||
|
String message = "Hello from DTLS 1.3 client!";
|
||||||
|
appData.clear();
|
||||||
|
appData.put(message.getBytes());
|
||||||
|
appData.flip();
|
||||||
|
|
||||||
|
/* Wrap the message */
|
||||||
|
netData.clear();
|
||||||
|
engine.wrap(appData, netData);
|
||||||
|
netData.flip();
|
||||||
|
|
||||||
|
/* Send message to server */
|
||||||
|
byte[] messageData = new byte[netData.remaining()];
|
||||||
|
netData.get(messageData);
|
||||||
|
DatagramPacket messagePacket = new DatagramPacket(
|
||||||
|
messageData, messageData.length, serverAddress, serverPort);
|
||||||
|
socket.send(messagePacket);
|
||||||
|
|
||||||
|
/* Receive response from server */
|
||||||
|
peerNetData.clear();
|
||||||
|
DatagramPacket responsePacket = new DatagramPacket(
|
||||||
|
peerNetData.array(), peerNetData.capacity());
|
||||||
|
socket.receive(responsePacket);
|
||||||
|
peerNetData.position(responsePacket.getLength());
|
||||||
|
peerNetData.flip();
|
||||||
|
|
||||||
|
/* Unwrap the response */
|
||||||
|
peerAppData.clear();
|
||||||
|
engine.unwrap(peerNetData, peerAppData);
|
||||||
|
peerAppData.flip();
|
||||||
|
|
||||||
|
/* Read the server's response */
|
||||||
|
byte[] serverMsg = new byte[peerAppData.remaining()];
|
||||||
|
peerAppData.get(serverMsg);
|
||||||
|
System.out.println("Received from server: " + new String(serverMsg));
|
||||||
|
|
||||||
|
/* Close the connection */
|
||||||
|
engine.closeOutbound();
|
||||||
|
|
||||||
|
/* Send close_notify */
|
||||||
|
netData.clear();
|
||||||
|
SSLEngineResult closeResult = engine.wrap(appData, netData);
|
||||||
|
netData.flip();
|
||||||
|
byte[] closeData = new byte[netData.remaining()];
|
||||||
|
netData.get(closeData);
|
||||||
|
DatagramPacket closePacket = new DatagramPacket(
|
||||||
|
closeData, closeData.length, serverAddress, serverPort);
|
||||||
|
socket.send(closePacket);
|
||||||
|
|
||||||
|
/* Wait for server's close_notify */
|
||||||
|
peerNetData.clear();
|
||||||
|
DatagramPacket closeResponsePacket = new DatagramPacket(
|
||||||
|
peerNetData.array(), peerNetData.capacity());
|
||||||
|
socket.setSoTimeout(5000); // Set timeout for close_notify
|
||||||
|
try {
|
||||||
|
socket.receive(closeResponsePacket);
|
||||||
|
peerNetData.position(closeResponsePacket.getLength());
|
||||||
|
peerNetData.flip();
|
||||||
|
engine.unwrap(peerNetData, peerAppData);
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
/* Timeout waiting for server close_notify, continue */
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Connection closed");
|
||||||
|
socket.close();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new SSLEngineClientDTLS13();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./lib/:/usr/local/lib
|
||||||
|
java -classpath ./lib/wolfssl.jar:./lib/wolfssl-jsse.jar:./examples/build -Dsun.boot.library.path=./lib/ -Dwolfjsse.debug=true SSLEngineClientDTLS13 $@
|
|
@ -0,0 +1,292 @@
|
||||||
|
/* SSLEngineServerDTLS13.java
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfSSL.
|
||||||
|
*
|
||||||
|
* wolfSSL is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfSSL is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example DTLS 1.3 server using SSLEngine.
|
||||||
|
*
|
||||||
|
* This server waits in an infinite loop for client connections, and when
|
||||||
|
* connected creates a new thread for each connection. This example is compiled
|
||||||
|
* when 'ant examples' is run in the package root.
|
||||||
|
*
|
||||||
|
* $ ant examples
|
||||||
|
* $ ./examples/provider/SSLEngineServerDTLS13.sh
|
||||||
|
*
|
||||||
|
* For testing, connect with the SSLEngineClientDTLS13 example:
|
||||||
|
*
|
||||||
|
* $ ./examples/provider/SSLEngineClientDTLS13.sh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.nio.channels.*;
|
||||||
|
import javax.net.ssl.*;
|
||||||
|
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
||||||
|
import java.security.*;
|
||||||
|
import com.wolfssl.provider.jsse.WolfSSLProvider;
|
||||||
|
|
||||||
|
public class SSLEngineServerDTLS13 {
|
||||||
|
/* Keystore and connection settings */
|
||||||
|
private char[] psw;
|
||||||
|
private String serverKS = "./examples/provider/server.jks";
|
||||||
|
private String serverTS = "./examples/provider/ca-client.jks";
|
||||||
|
private String jsseProv = "wolfJSSE";
|
||||||
|
private int serverPort = 11119;
|
||||||
|
|
||||||
|
/* Initialize password from environment or system property */
|
||||||
|
{
|
||||||
|
String password = System.getProperty("javax.net.ssl.keyStorePassword");
|
||||||
|
if (password == null) {
|
||||||
|
password = System.getenv("WOLFSSL_PASSWORD");
|
||||||
|
}
|
||||||
|
if (password == null) {
|
||||||
|
System.err.println("Warning: Using empty password. Set password with " +
|
||||||
|
"javax.net.ssl.keyStorePassword property or WOLFSSL_PASSWORD env var");
|
||||||
|
password = "";
|
||||||
|
}
|
||||||
|
psw = password.toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSLEngineServerDTLS13() {
|
||||||
|
try {
|
||||||
|
Security.addProvider(new WolfSSLProvider());
|
||||||
|
|
||||||
|
/* Set up KeyStore */
|
||||||
|
KeyStore serverKeyStore = KeyStore.getInstance("JKS");
|
||||||
|
serverKeyStore.load(new FileInputStream(serverKS), psw);
|
||||||
|
|
||||||
|
KeyManagerFactory km = KeyManagerFactory
|
||||||
|
.getInstance("SunX509", jsseProv);
|
||||||
|
km.init(serverKeyStore, psw);
|
||||||
|
|
||||||
|
/* Set up CA TrustManagerFactory */
|
||||||
|
KeyStore caKeyStore = KeyStore.getInstance("JKS");
|
||||||
|
caKeyStore.load(new FileInputStream(serverTS), psw);
|
||||||
|
|
||||||
|
TrustManagerFactory tm = TrustManagerFactory
|
||||||
|
.getInstance("SunX509", jsseProv);
|
||||||
|
tm.init(caKeyStore);
|
||||||
|
|
||||||
|
/* Create SSLContext for DTLS 1.3 */
|
||||||
|
SSLContext ctx = SSLContext.getInstance("DTLSv1.3", jsseProv);
|
||||||
|
ctx.init(km.getKeyManagers(), tm.getTrustManagers(), null);
|
||||||
|
|
||||||
|
/* Create DatagramSocket for DTLS */
|
||||||
|
DatagramSocket serverSocket = new DatagramSocket(serverPort);
|
||||||
|
System.out.println("DTLS 1.3 Server listening on port " + serverPort);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
/* Create buffer for client's initial message */
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
||||||
|
|
||||||
|
/* Wait for client connection */
|
||||||
|
serverSocket.receive(packet);
|
||||||
|
|
||||||
|
/* Create and start new client handler thread */
|
||||||
|
ClientHandler client = new ClientHandler(ctx, serverSocket, packet);
|
||||||
|
client.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClientHandler extends Thread {
|
||||||
|
private SSLEngine engine;
|
||||||
|
private DatagramSocket socket;
|
||||||
|
private DatagramPacket clientPacket;
|
||||||
|
private InetAddress clientAddress;
|
||||||
|
private int clientPort;
|
||||||
|
|
||||||
|
public ClientHandler(SSLContext ctx, DatagramSocket s,
|
||||||
|
DatagramPacket p) {
|
||||||
|
socket = s;
|
||||||
|
clientPacket = p;
|
||||||
|
clientAddress = p.getAddress();
|
||||||
|
clientPort = p.getPort();
|
||||||
|
|
||||||
|
/* Create SSLEngine for this client */
|
||||||
|
engine = ctx.createSSLEngine(clientAddress.getHostAddress(),
|
||||||
|
clientPort);
|
||||||
|
engine.setUseClientMode(false);
|
||||||
|
engine.setNeedClientAuth(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
/* Configure SSLEngine for DTLS */
|
||||||
|
SSLSession session = engine.getSession();
|
||||||
|
int appBufferSize = session.getApplicationBufferSize();
|
||||||
|
int netBufferSize = session.getPacketBufferSize();
|
||||||
|
|
||||||
|
/* Start handshake */
|
||||||
|
engine.beginHandshake();
|
||||||
|
|
||||||
|
/* Process handshake and data exchange */
|
||||||
|
handleConnection();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleConnection() {
|
||||||
|
try {
|
||||||
|
SSLSession session = engine.getSession();
|
||||||
|
ByteBuffer appData = ByteBuffer.allocate(session.getApplicationBufferSize());
|
||||||
|
ByteBuffer netData = ByteBuffer.allocate(session.getPacketBufferSize());
|
||||||
|
ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
|
||||||
|
ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
|
||||||
|
|
||||||
|
HandshakeStatus status = engine.getHandshakeStatus();
|
||||||
|
boolean handshakeComplete = false;
|
||||||
|
|
||||||
|
/* Handle handshake */
|
||||||
|
while (!handshakeComplete) {
|
||||||
|
switch (status) {
|
||||||
|
case NEED_UNWRAP:
|
||||||
|
/* Receive data from client */
|
||||||
|
peerNetData.clear();
|
||||||
|
DatagramPacket packet = new DatagramPacket(
|
||||||
|
peerNetData.array(), peerNetData.capacity());
|
||||||
|
socket.receive(packet);
|
||||||
|
peerNetData.position(packet.getLength());
|
||||||
|
peerNetData.flip();
|
||||||
|
|
||||||
|
/* Unwrap received data */
|
||||||
|
SSLEngineResult result = engine.unwrap(peerNetData, peerAppData);
|
||||||
|
peerNetData.compact();
|
||||||
|
status = result.getHandshakeStatus();
|
||||||
|
|
||||||
|
/* Handle tasks */
|
||||||
|
if (status == HandshakeStatus.NEED_TASK) {
|
||||||
|
Runnable task;
|
||||||
|
while ((task = engine.getDelegatedTask()) != null) {
|
||||||
|
task.run();
|
||||||
|
}
|
||||||
|
status = engine.getHandshakeStatus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NEED_WRAP:
|
||||||
|
/* Wrap handshake data */
|
||||||
|
netData.clear();
|
||||||
|
SSLEngineResult wrapResult = engine.wrap(appData, netData);
|
||||||
|
status = wrapResult.getHandshakeStatus();
|
||||||
|
|
||||||
|
/* Send wrapped data to client */
|
||||||
|
netData.flip();
|
||||||
|
byte[] data = new byte[netData.remaining()];
|
||||||
|
netData.get(data);
|
||||||
|
DatagramPacket sendPacket = new DatagramPacket(
|
||||||
|
data, data.length, clientAddress, clientPort);
|
||||||
|
socket.send(sendPacket);
|
||||||
|
|
||||||
|
/* Handle tasks */
|
||||||
|
if (status == HandshakeStatus.NEED_TASK) {
|
||||||
|
Runnable task;
|
||||||
|
while ((task = engine.getDelegatedTask()) != null) {
|
||||||
|
task.run();
|
||||||
|
}
|
||||||
|
status = engine.getHandshakeStatus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FINISHED:
|
||||||
|
handshakeComplete = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NOT_HANDSHAKING:
|
||||||
|
handshakeComplete = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Invalid handshake status: " + status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handshake complete, now exchange application data */
|
||||||
|
System.out.println("Handshake completed, waiting for data from client");
|
||||||
|
|
||||||
|
/* Receive data from client */
|
||||||
|
peerNetData.clear();
|
||||||
|
DatagramPacket dataPacket = new DatagramPacket(
|
||||||
|
peerNetData.array(), peerNetData.capacity());
|
||||||
|
socket.receive(dataPacket);
|
||||||
|
peerNetData.position(dataPacket.getLength());
|
||||||
|
peerNetData.flip();
|
||||||
|
|
||||||
|
/* Unwrap received data */
|
||||||
|
peerAppData.clear();
|
||||||
|
SSLEngineResult dataResult = engine.unwrap(peerNetData, peerAppData);
|
||||||
|
peerAppData.flip();
|
||||||
|
|
||||||
|
/* Read the client message */
|
||||||
|
byte[] clientMsg = new byte[peerAppData.remaining()];
|
||||||
|
peerAppData.get(clientMsg);
|
||||||
|
String message = new String(clientMsg);
|
||||||
|
System.out.println("Received from client: " + message);
|
||||||
|
|
||||||
|
/* Echo the message back to client */
|
||||||
|
appData.clear();
|
||||||
|
appData.put(clientMsg);
|
||||||
|
appData.flip();
|
||||||
|
|
||||||
|
/* Wrap the response */
|
||||||
|
netData.clear();
|
||||||
|
engine.wrap(appData, netData);
|
||||||
|
netData.flip();
|
||||||
|
|
||||||
|
/* Send response to client */
|
||||||
|
byte[] responseData = new byte[netData.remaining()];
|
||||||
|
netData.get(responseData);
|
||||||
|
DatagramPacket responsePacket = new DatagramPacket(
|
||||||
|
responseData, responseData.length, clientAddress, clientPort);
|
||||||
|
socket.send(responsePacket);
|
||||||
|
|
||||||
|
/* Close the connection */
|
||||||
|
engine.closeOutbound();
|
||||||
|
|
||||||
|
/* Send close_notify */
|
||||||
|
netData.clear();
|
||||||
|
SSLEngineResult closeResult = engine.wrap(appData, netData);
|
||||||
|
netData.flip();
|
||||||
|
byte[] closeData = new byte[netData.remaining()];
|
||||||
|
netData.get(closeData);
|
||||||
|
DatagramPacket closePacket = new DatagramPacket(
|
||||||
|
closeData, closeData.length, clientAddress, clientPort);
|
||||||
|
socket.send(closePacket);
|
||||||
|
|
||||||
|
System.out.println("Connection closed");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new SSLEngineServerDTLS13();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./lib/:/usr/local/lib
|
||||||
|
java -classpath ./lib/wolfssl.jar:./lib/wolfssl-jsse.jar:./examples/build -Dsun.boot.library.path=./lib/ -Dwolfjsse.debug=true SSLEngineServerDTLS13 $@
|
Loading…
Reference in New Issue