I am trying to create a client - server application, the client written in c++ and QT, and the server in java, but I am having a really hard time trying to get ssl encryption working.
The process fails at handshake level, I think. The reason why I am having such a difficult time trying to figure out why it is not working is because, even though the process fails, no errors are reported in either the client or the server. I use the fallowing an the client side, in QT :
this->_uCertificate.fromPath(_DC::DEFAULT_CERT_MAIN_PATH + _DC::DEFAULT_MAIN_CERT_FILE);
this->_socket->addCaCertificate(this->_uCertificate);
//begin connection
this->_socket->connectToHostEncrypted(this->_uServerAdress, this->_uServerPort);
//wait until connection has completed
if(!this->_socket->waitForConnected(_CM::TIMEOUT))
{
this->_lastError = this->_socket->errorString();
return false;
}
//wait for handshake
if ( !this->_socket->waitForEncrypted(_CM::TIMEOUT) ) {
this->_lastError = this->_socket->errorString(); //the error is "No Error"
//return false;
}
It fails when calling the "waitForEncrypted". The function return false, so the process failed, but the error string is "No Error". I have also added a slot for handling the error signal from the socket, but it is never called. On the server side I use :
SSLSocket _sock = (SSLSocket) this._ssocket.accept();
_sock.startHandshake();
........................................
if(this._inputBuffered.read(this._messageBuffer) < 0)
throw new Exception("Error while reading from client");
Again no exceptions are thrown, but it fails at the read command. But on the server side I am no sure if an exception is thrown if the connection / handshake fails, or I should check for the error manually somehow.
I used to have a problem , in the client, when I would receive an error that the common name doesn't match the host, so at least I know that the connection is somewhat working. After I fixed the certificate to include the right common name, I am receiving this none existing error. Does anyone have an idea why it would fail this way, or at least a better debugging method?
Edit I have tried to connect using openSSL and it works. The handshake succeeds, and I can send and receive packets from the server. So the problem seems to be in the client.
It seemed that I had a problem with the way I was loading certificates from file. The method "fromPath" apparently doesn't actually load a cert from file, but returnes a list of certificates. If I add this list to my socket, then it works as it should. I am a bit conscience-stricken that I didn't read the documentation properly.
Edit The reason why it was failing, but still no errors were thrown with signals is because my socket had no valid certificate. When I was calling this->_uCertificate.fromPath(..), the method was returning a list of certificates found at that path, but the object itself was not modified. It still remained a invalid, empty certificate. So when I added that empty certificate in my socket, the only one, when it reached the handshake, It had no valid certificate for the operation. At this point it fails, but no errors are thrown.
But when the objects returned by the .fromPath() methon are added to the socket, then the handshake continues as normal, because now it has valid and non empty cartificates.
The problem of failing to give an error when there's an empty certificate database is now Qt bug QTBUG-17550
Connect your SSL client socket's void QSslSocket::sslErrors ( const QList<QSslError> & errors ) signal to some slot and see if there are any SSL errors reported.
Related
I am trying to connect to an external server from my Solaris server using SSH in my Java application. Some how we are getting exception while authenticating the user but after 60min. How can we decrease the timing to get the exception to 5min or so.
There was a problem while connecting to IP:PORT
java.io.IOException: There was a problem while connecting to IP:PORT
The time difference between time2 and time3 are around 60min. I want to decrease this time.
Please find below the code snippet that we are using.
try
{
timeout = 1;
if (connection == null)
{
//time1
connection = new ch.ethz.ssh2.Connection(getIpAddress(), Integer.parseInt(getPort()));
if (connection == null)
{
System.out.println("connection is null");
}
else
{
//time2
connection.connect(null, timeout, 0);
}
}
}
catch (Exception t)
{
//time3
System.out.println(t.getLocalizedMessage());
System.out.println(t.toString());
}
Edit1: After checking SSH related configuration files I found KeyRegenerationInterval having a value of 3600s. Is this useful to resolve this issue. What might be the outcome if I decrease its value to some 30min or 5min.
Let me summarize your problem, please correct me if something wrong.
You can not connect to SSH server.
An exception raised after 60 mins.
According to below Throws section of method connect(ServerHostKeyVerifier, int, int), I guess you might be facing issue due to a buggy proxy which doesn't return proper HTTP response. Using direct internet connection to see whether the issue is gone.
Throws:
java.io.IOException - If any problem occurs, e.g., the server's host key is not accepted by the verifier or there is problem during
the initial crypto setup (e.g., the signature sent by the server is
wrong).
In case of a timeout (either connectTimeout or kexTimeout) a SocketTimeoutException is thrown.
An exception may also be thrown if the connection was already successfully connected (no matter if the connection broke in the mean
time) and you invoke connect() again without having called close()
first.
If a HTTP proxy is being used and the proxy refuses the connection, then a HTTPProxyException may be thrown, which contains
the details returned by the proxy. If the proxy is buggy and does not
return a proper HTTP response, then a normal IOException is thrown
instead.
Try setting the "kexTimeout" (Timeout for complete connection establishment (non-negative, in milliseconds). Zero means no timeout.) to non-zero
connection.connect(null, timeout, timeout);
Also, in your catch print the full stacktrace to verify where the timeout occurs
catch (Exception t) {
//time3
t.printStackTrace();
}
I'm using TinyRadius library and a FreeRadius server for authentication in a Spring boot app. Authentication works fine for about 4 requests, then I start getting "Error occurred while authenticating user. Message: bad packet: invalid packet identifier (request: 5, response: 4") The request number matches the one I see in the FreeRadius server by the way.
I had the same problem and I had deployed some workaround. This kind of problem in my situation was very rare. In case of RadiusException I use close() method to close socket and I am creating new object of RadiusClient class, which has the same hostname and secret as old RadiusClient object. In other way I recreate Radius socket. Maybe it's not the best solution, but I didn't want to modify code of TinyRadius library.
I need some help with the following problem:
I open a tcp-socket in the constructor then proceed to provide a object over an object output-stream to the server. I have no control over the server and don't get any response back.
How can I detect that the connection was lost? Will I always get the IOExeption-Error when trying to write? Because according to javadoc once a connection was successfully made most of the checks are basically useless to me.
Additionally what is the best way to reconnect a socket? Set the reference to "Null" then create a new one?
Here is my current approach:
I have a status-list in which I have the following statuses:
SocketSuccess; SocketFailure; MessageSuccess; MessageFailure;
My idea is kind of like a state-machine so check first what the last status was. If the connection was successfull or the last message was successfull then try to send the message. When I get a IOExeption then set the status MessageFailure, save the Message locally till I get a successfull connection again.
Or are there any recommended patterns for this kind of situation?
Clearing all your douts. If the connection with the server is lost then the client will throw IOException and that will kill the application but if you have handled the exception and tried to reconnect with the server and Re-establish the input output stream the your message function will start again. The predefined messages you are using will travel only when there is a connection between server and client. So when the connection is lost you will get IOException and when you handle that exception and try to reconnect a new input output stream should be established that will carry your messaging service.
I'm trying to connect an Android app to a SSL-enabled server, which uses a self-signed certificate. I've already read through dozens of tutorials and the app is now accepting the certificate & connecting to the server, but I never get any data back.
The original code i used to initialize the socket is this:
//passphrase for keystore
char[] keystorePass="password".toCharArray();
//load own keystore (MyApp just holds reference to application context)
KeyStore keyStore=KeyStore.getInstance("BKS");
keyStore.load(MyApp.getStaticApplicationContext().getResources().openRawResource(R.raw.keystore),keystorePass);
//create a factory
TrustManagerFactory trustManagerFactory=TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
//get context
SSLContext sslContext=SSLContext.getInstance("TLS");
//init context
sslContext.init(
null,
trustManagerFactory.getTrustManagers(),
new SecureRandom()
);
//create the socket
Socket socket=sslContext.getSocketFactory().createSocket("hostname",443);
socket.setKeepAlive(true);
Afterwards, the run loop of the receiver thread uses socket.getInputStream() to access the input stream.
As long as I use an unencrypted connection, this works without a problem. But the secure connection does not retrieve any data from the socket. I've verified this by adding log messages to the receive loop and even used OpenSSL's s_server to check. I retrieved data from the client, but the client never received anything I sent to it.
As a last test, I tried to open a connection to www.google.com:443 like this:
javax.net.SocketFactory fact=SSLSocketFactory.getDefault();
Socket socket=fact.createSocket(_config.getUri().getHost(), _config.getUri().getPort());
Still the same result, connection works but using the InputStream I receive nothing from the server.
Anybody got any ideas?
EDIT:
I'm currently not allowed to answer my own question, but here's the answer:
Well, turns out the problem WAS the receive loop. I relied on InputStream.available() to get the number of bytes to read, but didn't realize it was rather unreliable (always returns 0 for SSL socket). So I switched the receive loop to use the blocking read() instead.
As mentioned above: Turns out the problem WAS the receive loop. I relied on InputStream.available() to get the number of bytes to read, but didn't realize it was rather unreliable (always returns 0 for SSL socket). So I switched the receive loop to use the blocking read() instead.
So, I have a simple socket server and a socket. I run the socket server, successfully. The client socket connects and sends a string - this works. I want the server to write back different information based on this string. I can check what the string is and get an OutputStream to the client, but whenever I write to it and flush, the InputStream client-side is NEVER in a ready state, and will never get a message back... I just don't see what I'm doing wrong.
All the code is at http://pastebin.com/u/omegazero
NetworkAgent.java is the client, SimbadAgent.java is the server, and UserAgent.java is the actual implementation of said server (the server is abstract for other reasons).
Compile everything, then run UserAgent followed by NetworkAgent and you will see what happens.
Executed your code (after commenting the reference to StringQueue in SimbadAgent) and I got the following output.
wrote get_cmd
Input shutdown? false
iS()iI()iM()iB()iA()iD()i ()iB()iO()iO()iY()iA()NETWORKAGENT: Response to "get_cmd": "SIMBAD BOOYA"