-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JSSE: add basic RMI example client and server
- Loading branch information
Showing
8 changed files
with
502 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
|
||
# Java Remote Method Invocation (RMI) Example Client and Server | ||
|
||
This is a simple example of Java Remote Method Invocation (RMI), including | ||
the implementation of a very basic client (RmiClient.java) and server | ||
(RmiServer.java) with associated remote object interface definition | ||
(RmiRemoteInterface.java). These examples are set up to work over SSL/TLS. | ||
|
||
The `RmiRemoteInterface.java` file defines an interface with one public method | ||
named `String getServerMessage() throws RemoteException;`. This method | ||
should be implemented to one that returns a simple string message from the | ||
server implementation. | ||
|
||
The `RmiServer.java` file implements a simple server, which implements the | ||
`RemoteInterface` class and `getServerMessage()` method. The server binds | ||
an object with the stub "RemoteInterface" to the local default registry at | ||
localhost:1099. | ||
|
||
The `RmiClient.java` file gets an object stub from the remote registry, and | ||
makes the remote method invocation for `getServerMessage()`. | ||
|
||
## Compiling Example Code | ||
|
||
The example code is set up to compile as part of the `ant examples` target: | ||
|
||
``` | ||
$ cd wolfssljni | ||
$ ./java.sh | ||
$ ant | ||
$ ant examples | ||
``` | ||
|
||
## Start the Server | ||
|
||
To start the server, run the following helper script from the wolfSSL JNI/JSSE | ||
root directory: | ||
|
||
``` | ||
$ cd wolfssljni | ||
$ ./examples/provider/rmi/RmiServer.sh | ||
``` | ||
|
||
You should see the following message after the server has finished setting up | ||
the RMI object: | ||
|
||
``` | ||
Created server TrustManagerFactory | ||
Created server KeyManagerFactory | ||
Created server SSLContext | ||
Created server SSLServerSocketFactory | ||
Creating server Socket | ||
Created server TrustManagerFactory | ||
Created server KeyManagerFactory | ||
Created server SSLContext | ||
Created server SSLServerSocketFactory | ||
Server started, listening for connections | ||
``` | ||
|
||
## Connecting the Client | ||
|
||
To start the client, run the following helper script from the wolfSSL JNI/JSSE | ||
root directory: | ||
|
||
``` | ||
$ cd wolfssljni | ||
$ ./examples/provider/rmi/RmiClient.sh | ||
``` | ||
|
||
You should see the response sent back from the server method: | ||
|
||
``` | ||
Created client TrustManagerFactory | ||
Created client KeyManagerFactory | ||
Created client SSLContext | ||
Created client SocketFactory | ||
Creating client Socket | ||
Created client TrustManagerFactory | ||
Created client KeyManagerFactory | ||
Created client SSLContext | ||
Created client SocketFactory | ||
Creating client Socket | ||
Message from server via RMI: Hello from server | ||
``` | ||
|
||
## Support | ||
|
||
For support or questions with these examples, please email [email protected]. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* RmiClient.java | ||
* | ||
* Copyright (C) 2006-2024 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 | ||
*/ | ||
|
||
import java.net.InetAddress; | ||
import java.rmi.server.RMIClientSocketFactory; | ||
import java.rmi.registry.LocateRegistry; | ||
import java.rmi.registry.Registry; | ||
import java.security.Security; | ||
|
||
import com.wolfssl.WolfSSL; | ||
import com.wolfssl.provider.jsse.WolfSSLProvider; | ||
|
||
/** | ||
* Client class calling remote object interface on Server via RMI. | ||
*/ | ||
public class RmiClient | ||
{ | ||
/* RMI registry port, needs to be same as Server.java has */ | ||
private static final int registryPort = 11115; | ||
|
||
public RmiClient() { | ||
/* Default constructor */ | ||
} | ||
|
||
public static void main(String[] args) { | ||
|
||
try { | ||
|
||
/* Register wolfJSSE as top priority JSSE provider */ | ||
WolfSSL.loadLibrary(); | ||
Security.insertProviderAt(new WolfSSLProvider(), 1); | ||
|
||
/* Server hostname, null indicates localhost */ | ||
String host = InetAddress.getLocalHost().getHostName(); | ||
|
||
/* Get stub for the SSL/TLS registry on specified host */ | ||
Registry registry = LocateRegistry.getRegistry(host, registryPort, | ||
new RmiTLSClientSocketFactory()); | ||
|
||
/* Invoke lookup on remote registry to get remote object stub */ | ||
RmiRemoteInterface ri = | ||
(RmiRemoteInterface)registry.lookup("RmiRemoteInterface"); | ||
|
||
/* Call remote method, get back server response */ | ||
String serverMessage = ri.getServerMessage(); | ||
System.out.println("Message from server via RMI: " + serverMessage); | ||
|
||
} catch (Exception e) { | ||
|
||
System.out.println("Client exception: " + e.toString()); | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/bash | ||
|
||
cd ./examples/build | ||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../lib/:/usr/local/lib | ||
java -classpath ../../lib/wolfssl.jar:../../lib/wolfssl-jsse.jar:./ -Dsun.boot.library.path=../../lib/ RmiClient "$@" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* RmiRemoteInterface.java | ||
* | ||
* Copyright (C) 2006-2024 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 | ||
*/ | ||
|
||
import java.rmi.Remote; | ||
import java.rmi.RemoteException; | ||
|
||
/** | ||
* Interface defining the remote object interface. | ||
*/ | ||
public interface RmiRemoteInterface extends Remote { | ||
String getServerMessage() throws RemoteException; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* RmiServer.java | ||
* | ||
* Copyright (C) 2006-2024 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 | ||
*/ | ||
|
||
import java.rmi.registry.Registry; | ||
import java.rmi.registry.LocateRegistry; | ||
import java.rmi.RemoteException; | ||
import java.rmi.server.UnicastRemoteObject; | ||
import java.security.Security; | ||
|
||
import com.wolfssl.WolfSSL; | ||
import com.wolfssl.provider.jsse.WolfSSLProvider; | ||
|
||
/** | ||
* Server class implementing RemoteInterface.getServerMessage() interface. | ||
*/ | ||
public class RmiServer extends UnicastRemoteObject implements RmiRemoteInterface | ||
{ | ||
private static final int registryPort = 11115; | ||
|
||
public RmiServer() throws Exception { | ||
super(registryPort, | ||
new RmiTLSClientSocketFactory(), | ||
new RmiTLSServerSocketFactory()); | ||
} | ||
|
||
/** | ||
* Return message from server. Implementation of | ||
* RmiRemoteInterface.getServerHello(), callable via RMI from client. | ||
*/ | ||
public String getServerMessage() { | ||
return "Hello from server"; | ||
} | ||
|
||
public static void main(String[] args) { | ||
|
||
try { | ||
/* Register wolfJSSE as top priority JSSE provider */ | ||
WolfSSL.loadLibrary(); | ||
Security.insertProviderAt(new WolfSSLProvider(), 1); | ||
|
||
/* Register object with Java RMI registry. Create new registry | ||
* using SSL/TLS on specified port. If bind() fails, will throw | ||
* a RemoteException. */ | ||
Registry registry = LocateRegistry.createRegistry(registryPort, | ||
new RmiTLSClientSocketFactory(), new RmiTLSServerSocketFactory()); | ||
|
||
/* Create and export a remote object */ | ||
RmiServer srv = new RmiServer(); | ||
registry.bind("RmiRemoteInterface", srv); | ||
|
||
System.out.println("Server started, listening for connections"); | ||
|
||
} catch (Exception e) { | ||
|
||
System.out.println("Server exception: " + e.toString()); | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/bash | ||
|
||
cd ./examples/build | ||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../lib/:/usr/local/lib | ||
java -classpath ../../lib/wolfssl-jsse.jar:./ -Dsun.boot.library.path=../../lib/ RmiServer "$@" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* RmiTLSClientSocketFactory.java | ||
* | ||
* Copyright (C) 2006-2024 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 | ||
*/ | ||
|
||
import java.rmi.server.RMIClientSocketFactory; | ||
import java.io.Serializable; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.security.KeyStore; | ||
import java.net.Socket; | ||
import javax.net.SocketFactory; | ||
import javax.net.ssl.SSLSocket; | ||
import javax.net.ssl.SSLContext; | ||
import javax.net.ssl.KeyManagerFactory; | ||
import javax.net.ssl.TrustManagerFactory; | ||
|
||
public class RmiTLSClientSocketFactory | ||
implements RMIClientSocketFactory, Serializable | ||
{ | ||
|
||
public RmiTLSClientSocketFactory() { | ||
} | ||
|
||
public Socket createSocket(String host, int port) throws IOException { | ||
|
||
/* Keystore holding client key and cert */ | ||
String clientJKS = "../provider/client.jks"; | ||
String clientPass = "wolfSSL test"; | ||
/* Keystore holding CA certs to verify server */ | ||
String caJKS = "../provider/ca-server.jks"; | ||
String caPass = "wolfSSL test"; | ||
String keystoreFormat = "JKS"; | ||
|
||
/* TLS protocol version - "TLS" uses highest compiled in */ | ||
String tlsVersion = "TLS"; | ||
|
||
SSLContext ctx; | ||
TrustManagerFactory tm; | ||
KeyManagerFactory km; | ||
KeyStore cert, pKey; | ||
SocketFactory sf = null; | ||
|
||
try { | ||
/* Create TrustManagerFactory with certs to verify peer */ | ||
tm = TrustManagerFactory.getInstance("SunX509"); | ||
cert = KeyStore.getInstance(keystoreFormat); | ||
cert.load(new FileInputStream(caJKS), caPass.toCharArray()); | ||
tm.init(cert); | ||
System.out.println("Created client TrustManagerFactory"); | ||
|
||
/* Create KeyManagerFactory with client cert/key */ | ||
pKey = KeyStore.getInstance(keystoreFormat); | ||
pKey.load(new FileInputStream(clientJKS), clientPass.toCharArray()); | ||
km = KeyManagerFactory.getInstance("SunX509"); | ||
km.init(pKey, clientPass.toCharArray()); | ||
System.out.println("Created client KeyManagerFactory"); | ||
|
||
/* Create SSLContext, doing peer auth */ | ||
ctx = SSLContext.getInstance(tlsVersion); | ||
ctx.init(km.getKeyManagers(), tm.getTrustManagers(), null); | ||
System.out.println("Created client SSLContext"); | ||
|
||
/* Create SocketFactory */ | ||
sf = ctx.getSocketFactory(); | ||
System.out.println("Created client SocketFactory"); | ||
|
||
} catch (Exception e) { | ||
System.out.println("Exception when creating client SocketFactory"); | ||
e.printStackTrace(); | ||
} | ||
|
||
System.out.println("Creating client Socket"); | ||
return (SSLSocket)sf.createSocket(host, port); | ||
} | ||
|
||
public int hashCode() { | ||
return getClass().hashCode(); | ||
} | ||
|
||
public boolean equals(Object obj) { | ||
if (obj == this) { | ||
return true; | ||
} | ||
else if (obj == null || (obj.getClass() != getClass())) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
} | ||
|
Oops, something went wrong.