I'm trying to update an old RESTful API to allow it to serve https; I don't actually need the added security but I've got clients complaining about mixed context - this is on a deployed desktop application that is just using REST to communicate; not a deployed web app.
This is a jersey 1 implementation and I'm trying to avoid having to upgrade to Jersey 2. The HTTP serving was very easy:
this.server = HttpServerFactory.create(baseUri,
new DefaultResourceConfig(DataPaqResource.class));
So I've looked around and pulled from the javadocs the following to start https or http based on the base uri passed in:
StartWebServer(String baseUri) throws IOException, NoSuchAlgorithmException{
ResourceListeners.addDataPaqResourceListener(this);
if (baseUri.startsWith("https")) {
SSLContext sslContext = SSLContext.getInstance ("SSL");
this.server = (HttpsServer) HttpServerFactory.create(baseUri,
new DefaultResourceConfig(DataPaqResource.class));
((HttpsServer) this.server).setHttpsConfigurator (new HttpsConfigurator(sslContext) {
public void configure (HttpsParameters params) {
SSLContext c = getSSLContext();
// get the default parameters
SSLParameters sslparams = c.getDefaultSSLParameters();
params.setSSLParameters(sslparams);
}
});
}else {
this.server = HttpServerFactory.create(baseUri,
new DefaultResourceConfig(DataPaqResource.class));
}
System.out.println("Started web server on " + baseUri + " imp " +
this.server.getClass().getName());
}
This works fine for http but with https I get:
Error: Client network socket disconnected before secure TLS connection was established
This error is from postman but obviously browsers fail too. Basically I know that the https is configured incorrectly but I'm not sure how to configure it. I don't need the security; I just need to be able to serve https with the minimal amount of configuration.
Any and all help gratefully received!
Solved it - it was basically all working except I loaded the keystore wrong!
//keystore generated with
//keytool -genkeypair -keyalg RSA -alias self_signed -keypass datapaq -keystore
//datapaq.keystore -storepass datapaq
public class StartWebServer implements DataPaqResourceListener{
private HttpServer server;
private static final String password = "datapaq";
StartWebServer(String baseUri) throws IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException{
ResourceListeners.addDataPaqResourceListener(this);
if (baseUri.startsWith("https")) {
this.server = (HttpsServer) HttpServerFactory.create(baseUri,
new DefaultResourceConfig(DataPaqResource.class));
SSLContext sslContext = SSLContext.getInstance ("SSL");
KeyStore ks = getKeyStore();
// Set up the key manager factory
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password.toCharArray());
// Set up the trust manager factory
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
// Set up the HTTPS context and parameters
((HttpsServer) this.server).setHttpsConfigurator (new HttpsConfigurator(sslContext) {
public void configure (HttpsParameters params) {
try {
// Initialise the SSL context
SSLContext context = getSSLContext();
SSLEngine engine = context.createSSLEngine();
engine.setNeedClientAuth(false);
engine.setWantClientAuth(false);
params.setNeedClientAuth(false);
params.setWantClientAuth(false);
params.setCipherSuites(engine.getEnabledCipherSuites());
params.setProtocols(engine.getEnabledProtocols());
// Set the SSL parameters
SSLParameters sslParameters = context.getSupportedSSLParameters();
params.setSSLParameters(sslParameters);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}else {
this.server = HttpServerFactory.create(baseUri,
new DefaultResourceConfig(DataPaqResource.class));
}
}
private KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException {
// Initialise the keystore
char[] password = "datapaq".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
InputStream fis = new FileInputStream("datapaq.keystore");
ks.load(fis, password);
return ks;
}
}