java secure socket without authentication? - java

I have a trivial secure socket server-client program.
For the server certificates, I created a keystore using keytool.
When I try to connect to the server by my client I get these exceptions:
In server:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
In client:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
If my understanding is correct, these exceptions are caused due to the fact, that I am using certificates I created.
My question is the following:
If I set in the enabled cipher suites, both in server and in client, all the *_anon* cipher suites, shouldn't this solved the problem?
I mean If I enable the *_anon_* cipher suites then no authentication would be needed hence no exceptions.
Is this correct?
Because I still get exceptions. I tried having in the enabled cipher suites all the enabled+the _anon ones. No success. I tried setting only the anon ones and got a new exception:
Exception in thread "main" java.lang.IllegalArgumentException: Name must not be null
Could someone please explain why I get these exceptions, with the anon cipher suites?
Note:
If I set on the client the system property javax.net.ssl.trustStore pointing to the keystore I created and being used by my server, the communication is fine!
The program works with no exceptions and the data are send ok, from client to server.
UPDATE:
This is the snippet I use to enable the anon ciphers (I have done this for server and client part):
String[] supported = server.getSupportedCipherSuites();
String[] anonCipherSuitesSupported = new String[supported.length];
int count = 0;
for(int i = 0; i < supported.length; i++)
{
if(supported[i].indexOf("_anon_") > 0)
{
anonCipherSuitesSupported[count++] = supported[i];
}
}
String[] oldEnabled = server.getEnabledCipherSuites();
String[] newEnabled = new String[oldEnabled.length + count];
System.arraycopy(oldEnabled, 0, newEnabled, 0, oldEnabled.length);
System.arraycopy(anonCipherSuitesSupported, 0, newEnabled, oldEnabled.length, count);
server.setEnabledCipherSuites(newEnabled);
The stack trace is on client side:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
at sun.nio.cs.StreamEncoder.flush(Unknown Source)
at java.io.OutputStreamWriter.flush(Unknown Source)
at com.client.SSLClient1.main(SSLClient1.java:58)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 14 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 20 more
and on server side:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at com.server.SecureOrderTaker.main(SecureOrderTaker.java:92)
Now if I simply do:
server.setEnabledCipherSuites(anonCipherSuitesSupported);
So that only the anon cipher suites are enabled I get:
Exception in thread "main" java.lang.IllegalArgumentException: Name must not be null
at com.sun.net.ssl.internal.ssl.CipherSuite.valueOf(Unknown Source)
at com.sun.net.ssl.internal.ssl.CipherSuiteList.<init>(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.setEnabledCipherSuites(Unknown Source)
at com.server.SecureOrderTaker.main(SecureOrderTaker.java:82)
Thank you

You are right, *_anon_* ciphers are used for a complete unauthenticated connection (both server and client are anonymous). With these cipher suites no certificate is required. I wrote a small code to test:
ServerSocketFactory sf = SSLServerSocketFactory.getDefault();
final SSLServerSocket socket = (SSLServerSocket)sf.createServerSocket(443);
System.out.println(Arrays.toString(socket.getSupportedCipherSuites()));
System.out.println(Arrays.toString(socket.getEnabledCipherSuites()));
socket.setEnabledCipherSuites(new String[] {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"});
Thread t = new Thread() {
public void run() {
try {
Socket client = socket.accept();
client.getOutputStream().write("Hello World\n".getBytes("ASCII"));
client.close();
} catch (IOException ioe) {
}
}
};
t.start();
Thread.sleep(2000);
SSLSocket client = (SSLSocket) SSLSocketFactory.getDefault().createSocket("localhost", 443);
client.setEnabledCipherSuites(new String[] {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"});
InputStream in = client.getInputStream();
byte[] data = new byte[1024];
int len = in.read(data);
System.out.println(new String(data, 0, len));
I know that this code is not perfect but I successfully exchange data between the client and the server. Maybe your server or client socket is not well configured. Can you give the full stacktrace you got?
Note that these ciphers are deprecated since there are vulnerable to man-in-the-middle attacks.
UPDATE : I found the issue. The anonCipherSuitesSupported array length is too long. Therefore after adding the *_anon_* the array is ending with a bunch of null values. And the implementation does not seem to accept null in the enabled cipher list.
String[] supported = server.getSupportedCipherSuites();
List<String> list= new ArrayList<String>();
for(int i = 0; i < supported.length; i++)
{
if(supported[i].indexOf("_anon_") > 0)
{
list.add(supported[i]);
}
}
String[] anonCipherSuitesSupported = list.toArray(new String[0]);

You're dealing with certificates created by you, meaning you are the Certification Authority.
Your problem is that in order for both sides to shake hands and communicate, they need to both trust each others' certificates. Trust is established by building the chain from the certificate up to the CA to see if the specific side trusts that CA (some additional steps such as checking whether the certificate hasn't been revoked might be in place as well). Most major CAs are trusted by default in Java. In your case, your custom CA is not.
That means that your server certificate should be in the trust store of your client (as you mentioned, pointing it solves the problem). That, or the CA's certificate (better choice).
Take a look here for general details on SSL/TLS.
If you're dealing with mutual trust then your server should trust the CA that issued your client certificate as well.

Related

Can't connect to MySQL Database with Java JDBC

I created a simple class to test the communication to my localhost database, that I created with Mysql Workbench. The Mysql Server is running. The JDBC Driver is added to the Classpath of my project.
public class Database
{
public static void main(String[] args)
throws SQLException, ClassNotFoundException
{
Connection connection = null;
String serverName = "localhost:3306";
String databaseName = "detector_tests";
String url = "jdbc:mysql://" + serverName + "/" + databaseName
+ "?useSSL=TRUE";
String username = "simon";
String password = "password123";
connection = DriverManager.getConnection(url, username, password);
}
}
When I run the program I get the followning Exception:
Exception in thread "main"
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications
link failure
The last packet sent successfully to the server was 0 milliseconds
ago. The driver has not received any packets from the server. at
com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:172)
at
com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
at
com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862)
at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:444)
at
com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230)
at
com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226)
at java.sql.DriverManager.getConnection(Unknown Source) at
java.sql.DriverManager.getConnection(Unknown Source) at
Database.main(Database.java:17) Caused by:
com.mysql.cj.exceptions.CJCommunicationsException: Communications link
failure
The last packet sent successfully to the server was 0 milliseconds
ago. The driver has not received any packets from the server. at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown
Source) at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown
Source) at java.lang.reflect.Constructor.newInstance(Unknown Source)
at
com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:59)
at
com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:103)
at
com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:149)
at
com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:165)
at
com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:355)
at
com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:789)
at
com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:499)
at
com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:217)
at
com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1411)
at com.mysql.cj.NativeSession.connect(NativeSession.java:165) at
com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:982)
at
com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:852)
... 6 more Caused by: javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException:
java.security.cert.CertPathValidatorException: Path does not chain
with any of the trust anchors at
sun.security.ssl.Alerts.getSSLException(Unknown Source) at
sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) at
sun.security.ssl.Handshaker.fatalSE(Unknown Source) at
sun.security.ssl.Handshaker.fatalSE(Unknown Source) at
sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source) at
sun.security.ssl.Handshaker.process_record(Unknown Source) at
sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) at
sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at
sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at
com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:213)
at
com.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java:206)
at
com.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection.java:99)
at
com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:350)
... 13 more Caused by: java.security.cert.CertificateException:
java.security.cert.CertPathValidatorException: Path does not chain
with any of the trust anchors at
com.mysql.cj.protocol.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:280)
at
sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unknown
Source) ... 25 more Caused by:
java.security.cert.CertPathValidatorException: Path does not chain
with any of the trust anchors at
sun.security.provider.certpath.PKIXCertPathValidator.validate(Unknown
Source) at
sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(Unknown
Source) at java.security.cert.CertPathValidator.validate(Unknown
Source) at
com.mysql.cj.protocol.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:273)
... 26 more
It appears that I need to add some kind of certificate or something. I m not sure, because I m quite new to databases. Anyone with the same experience or a solution? If you need anymore information I'm happy to edit the post.
Thanks in advance!
Seems you are trying to connect mysql database along with a certificate. If you are connecting to MySQL instance through TLS, you need to have a trust store to keep your certificates. Refer to this document to create MySQL connection along with a TLS connection.
But, you can ignore TLS validation by setting FALSE for "useSSL" in MySQL connection URL. Your code will be as follows.
public class Database
{
public static void main(String[] args)
throws SQLException, ClassNotFoundException
{
Connection connection = null;
String serverName = "localhost:3306";
String databaseName = "detector_tests";
String url = "jdbc:mysql://" + serverName + "/" + databaseName
+ "?useSSL=FALSE";
String username = "simon";
String password = "password123";
connection = DriverManager.getConnection(url, username, password);
}
}
Hope this will be the answer to your question.

Connecting to SFTP server using sinet factory

I was trying the below code to connect to an SFTP server
final String sftpURL = <<my hostname here>>;
final String username = <<username here>>;
final String password = <<password here>>;
SshParameters params = new SshParameters(sftpURL,username,password);
Sftp ftp = new Sftp(params);
// Connect, upload PNG images and release the connection.
ftp.connect();
ftp.disconnect();
When trying to connect it was throwing the below error:::
Exception in thread "main" com.jscape.inet.sftp.SftpException: SHA256 MessageDigest not available
at com.jscape.inet.sftp.SftpException.wrap(Unknown Source)
at com.jscape.inet.sftp.Sftp.a(Unknown Source)
at com.jscape.inet.sftp.Sftp.connect(Unknown Source)
at com.bcs.renewals.Test.main(Test.java:19)
Caused by: com.jscape.util.o.b: SHA256 MessageDigest not available
at com.jscape.util.o.b.a(Unknown Source)
at com.jscape.util.o.c.a(Unknown Source)
at com.jscape.inet.sftp.Sftp.b(Unknown Source)
... 2 more
Caused by: com.jscape.util.l.a.h: SHA256 MessageDigest not available
at com.jscape.inet.ssh.protocol.v2.connection.SessionConnector.connect(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.connection.SessionConnector.connect(Unknown Source)
at com.jscape.inet.sftp.SftpFileService3.actualStart(Unknown Source)
... 4 more
Caused by: com.jscape.util.l.a.b: SHA256 MessageDigest not available
at com.jscape.util.l.a.b.a(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.transport.TransportConnection.a(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.transport.TransportConnection.exchangeKeys(Unknown Source)
... 7 more
Caused by: java.security.NoSuchAlgorithmException: SHA256 MessageDigest not available
at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at java.security.Security.getImpl(Security.java:695)
at java.security.MessageDigest.getInstance(MessageDigest.java:167)
at com.jscape.a.f.a(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.transport.keyexchange.DiffieHellmanGroupKeyExchange.createHash(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.transport.keyexchange.DiffieHellmanGroupClientKeyExchange.exchangeKeys(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.transport.TransportConnection.handle(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.messages.SshMsgKexInit.accept(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.messages.SshMsgKexInit.accept(Unknown Source)
at com.jscape.inet.ssh.protocol.v2.transport.TransportConnection.c(Unknown Source)
... 9 more
The above code was working few months before. But now its throwing the error. I have downloaded a latest version of sinet-factory.jar as well. Can some one please help me in solving the issue?
The issue was beacause it requires one more jar bcprov-ext-jdk15on-148.jar in the CLASSPATH along with the sinetfactory.jar
I added that and the problem resolved.
Thanks.

Java HTTPS server code failing

I've been trying to implement a HTTPS/SSL server in Java, and I've tried using a number of different code examples, but they all seem to fail at the point that the server has read the request. Below is one example I've been working with, and when I run that with Firefox, I get this error:
[write] MD5 and SHA1 hashes: len = 16
0000: 14 00 00 0C 73 A7 11 73 AE 3C 41 C5 91 C7 E9 19 ....s..s.<A.....
Padded plaintext before ENCRYPTION: len = 16
0000: 14 00 00 0C 73 A7 11 73 AE 3C 41 C5 91 C7 E9 19 ....s..s.<A.....
main, WRITE: TLSv1.2 Handshake, length = 40
main, waiting for close_notify or alert: state 1
main, Exception while waiting for close java.net.SocketException: Software caused connection abort: recv failed
main, handling exception: java.net.SocketException: Software caused connection abort: recv failed
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
Priv exp --- null
Exception occurred .... java.net.SocketException: Software caused connection abort: recv failed
java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.waitForClose(Unknown Source)
at sun.security.ssl.HandshakeOutStream.flush(Unknown Source)
at sun.security.ssl.Handshaker.sendChangeCipherSpec(Unknown Source)
at sun.security.ssl.ServerHandshaker.sendChangeCipherAndFinish(Unknown Source)
at sun.security.ssl.ServerHandshaker.clientFinished(Unknown Source)
at sun.security.ssl.ServerHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at SSLServer.main(SSLServer.java:65)
and, here's the code:
import java.io.*;
import java.security.Security;
import java.security.PrivilegedActionException;
import javax.net.ssl.*;
import com.sun.net.ssl.*;
import com.sun.net.ssl.internal.ssl.Provider;
/**
* #author Joe Prasanna Kumar
* This program simulates an SSL Server listening on a specific port for client requests
*
* Algorithm:
* 1. Regsiter the JSSE provider
* 2. Set System property for keystore by specifying the keystore which contains the server certificate
* 3. Set System property for the password of the keystore which contains the server certificate
* 4. Create an instance of SSLServerSocketFactory
* 5. Create an instance of SSLServerSocket by specifying the port to which the SSL Server socket needs to bind with
* 6. Initialize an object of SSLSocket
* 7. Create InputStream object to read data sent by clients
* 8. Create an OutputStream object to write data back to clients.
*
*/
public class SSLServer {
/**
* #param args
*/
public static void main(String[] args) throws Exception{
int intSSLport = 4443; // Port where the SSL Server needs to listen for new requests from the client
{
// Registering the JSSE provider
Security.addProvider(new Provider());
//Specifying the Keystore details
System.setProperty("javax.net.ssl.keyStore","C:\\Users\\test\\Eclipse-workspaces\\Test\\newkeystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword","changeit");
// Enable debugging to view the handshake and communication which happens between the SSLClient and the SSLServer
System.setProperty("javax.net.debug","all");
}
try {
// Initialize the Server Socket
SSLServerSocketFactory sslServerSocketfactory = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket sslServerSocket = (SSLServerSocket)sslServerSocketfactory.createServerSocket(intSSLport);
SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
// Create Input / Output Streams for communication with the client
while(true)
{
PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
sslSocket.getInputStream()));
String inputLine, outputLine;
System.out.println("Start reading socket");
while ((inputLine = in.readLine()) != null) {
//out.println(inputLine);
System.out.println(inputLine);
}
System.out.println("Finished reading socket");
// Send the response
// Send the headers
out.println("HTTP/1.0 200 OK");
out.println("Content-Type: text/html");
out.println("Server: Bot");
// this blank line signals the end of the headers
out.println("");
// Send the HTML page
out.println("<H1>Welcome to the Ultra Mini-WebServer</H2>");
out.flush();
// Close the streams and the socket
out.close();
in.close();
sslSocket.close();
sslServerSocket.close();
}
}
catch(Exception exp)
{
PrivilegedActionException priexp = new PrivilegedActionException(exp);
System.out.println(" Priv exp --- " + priexp.getMessage());
System.out.println(" Exception occurred .... " +exp);
exp.printStackTrace();
}
}
}
As I said, I've tried a bunch of other example programs that are similar, and they all seem to fail at the same area, after the read of the request.
NOTE that if I use openssl s_client and type the same input request in manually it works.
Can anyone help point me to what might be wrong?
Thanks,
Jim
EDIT:
I think that I've made some progress, with a different example server code, the one from here:
http://www.herongyang.com/JDK/HTTPS-Server-Test-Program-HttpsHello.html
First of all, again, if I run this app and hit it from "openssl s_client", it works fine when I manually enter a "GET".
But, if I try using Firefox, as soon as I send a request to https://192.168.0.6:8888 (FYI, doesn't matter if I use a hostname that matches cert), I get a popup asking me to add an exception and ALSO, I get at the app/server end:
Server started:
Server socket class: class sun.security.ssl.SSLServerSocketImpl
Socket address = 0.0.0.0/0.0.0.0
Socket port = 8888
Need client authentication = false
Want client authentication = false
Use client mode = false
Socket class: class sun.security.ssl.SSLSocketImpl
Remote address = /192.168.0.5
Remote port = 58972
Local socket address = /192.168.0.5:8888
Local address = /192.168.0.5
Local port = 8888
Need client authentication = false
Cipher suite = SSL_NULL_WITH_NULL_NULL
Protocol = NONE
Read=[null]
java.net.SocketException: Connection closed by remote host
at sun.security.ssl.SSLSocketImpl.checkWrite(Unknown Source)
at sun.security.ssl.AppOutputStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
at sun.nio.cs.StreamEncoder.flush(Unknown Source)
at java.io.OutputStreamWriter.flush(Unknown Source)
at java.io.BufferedWriter.flush(Unknown Source)
at HttpsHello.main(HttpsHello.java:43)
So, I did something differently.
I started Firefox, then went to Options->Advanced->Certificates->Add Exception
For the exception, I put the URL to get the cert, https://192.168.0.5:8888
The app blew up as soon as I clicked "Get Certificate":
Server started:
Server socket class: class sun.security.ssl.SSLServerSocketImpl
Socket address = 0.0.0.0/0.0.0.0
Socket port = 8888
Need client authentication = false
Want client authentication = false
Use client mode = false
Socket class: class sun.security.ssl.SSLSocketImpl
Remote address = /192.168.0.5
Remote port = 59018
Local socket address = /192.168.0.5:8888
Local address = /192.168.0.5
Local port = 8888
Need client authentication = false
Cipher suite = SSL_NULL_WITH_NULL_NULL
Protocol = NONE
Read=[null]
java.net.SocketException: Connection closed by remote host
at sun.security.ssl.SSLSocketImpl.checkWrite(Unknown Source)
at sun.security.ssl.AppOutputStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
at sun.nio.cs.StreamEncoder.flush(Unknown Source)
at java.io.OutputStreamWriter.flush(Unknown Source)
at java.io.BufferedWriter.flush(Unknown Source)
at HttpsHello.main(HttpsHello.java:43)
BUT, Firefox let me add a temporary exception at this point!!
Ok, then after adding the temporary exception, I restarted the app, and put in https://192.168.0.5:8888 into the Firefox address, and, at that point, IT WORKED, i.e., I got the "Hello world" web page in Firefox!!
Does anyone know why this is happening? Why is it that "openssl s_client" works, but it blows up with Firefox, APPARENTLY when Firefox is getting the cert from the app to add the cert as an exception?
EDIT 2:
I posted in comments that I got this working on one of my laptops, but I still haven't gotten it working on my main development machine.
I am pasting in the SSL debug log from a test I just did at:
http://pastebin.com/faVCjj3a
If anyone can see anything that might be causing this please let me know? I did this test after moving over the exact JKS file and certs from the working system. Also, I've installed the unlimited strength policy jars on this other system.
Thanks...
EDIT 3: I think I've finally found an example that seems to work:
http://www.mybinarylife.net/2012/06/java-ssl-threaded-echo-server.html
I modified that code slightly to send HTTP response instead of just echoing the request, and it seems to work even with a browser like Firefox.
It appears that the difference between hitting the server with openssl s_client and a browser is that when the first request is made, and the browser finds some problem like the hostname not matching the cert or other situations, and when the browser like Firefox is asking for an exception, there is an SSL error, so the server has to be able to handle that and continue handling the request/connection, rather than just dying, which this new example seems to do.

java.lang.RuntimeException: Could not generate DH keypair when trying to make call to web service

I am making an HTTP call like this:
HttpPost httppost = new HttpPost(url);
HttpClient httpclient = HttpClients.createDefault();
//ent is MultipartEntityBuilder ent
httppost.setEntity(ent.build());
try {
HttpResponse response = httpclient.execute(httppost);****
I am getting the error at the line of code with the ****
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:279)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:257)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:132)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:349)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:365)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:221)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:199)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:87)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:109)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:84)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:109)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
I am not quite sure what is causing this. Could someone please tell me what is causing this? I am making a rest call to a web service
It appears you make an http connection and get redirected to https, which you are not handling. You are getting an SSL error. It cannot create the Diffie Hellman pair, which is an early part of SSL handshake.

not able to make connection using javamail api

I am trying to make connection to the mailserver using java mail api, with user loginId password and the host name. But if any one of the id fails to make connection then the following ids also fails to authorize even if they have correct credentials.
Do I've to close the store values after the loop.
sessions = Session.getDefaultInstance(properties);
store = sessions.getStore(emailAccType);
store.connect(emailHost,emailId, emailPwd);
What i need to close in finally block of try/catch.
for the following error.
javax.mail.MessagingException: Connect failed;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:161)
at javax.mail.Service.connect(Service.java:288)
at javax.mail.Service.connect(Service.java:169)
at com.scheduler.utils.QuartzImplementation.<init>(QuartzImplementation.java:77)
at com.scheduler.utils.SchedulerRedirect.execute(SchedulerRedirect.java:31)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)
Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
at com.sun.net.ssl.internal.ssl.InputRecord.handleUnknownRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readLine(Unknown Source)
at com.sun.mail.pop3.Protocol.simpleCommand(Protocol.java:360)
at com.sun.mail.pop3.Protocol.<init>(Protocol.java:104)
at com.sun.mail.pop3.POP3Store.getPort(POP3Store.java:214)
at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:157)
for the first time it's executing but if one fails then this problem arise.
Thanks in advance
Refer the answer to this question
Please ensure you've read the java mail API FAQs completely.

Categories

Resources