Make OpenSSL server only accept connections from clients that already have the server's public certificate - c++

I'm still learning to program in C++ using OpenSSL, and trying to build and application where the client initiates the connections to the server. I have
Generated a certificate/key pair using OpenSSL (as .pem)
Called the SSL_use_certificate_file/PrivateKey_file in the server's initialization
Store the server's certificate with the clien and verify the certificate on client side when trying to connect to server
I noticed that even when I passed an incorrect certificate to the client and (correctly) failed 3., the connection still goes through, and the client and server continue doing whatever they were originally supposed to do.
What I would like to ask is,
Is there something wrong with how I'm using the certificate?
How can I make it such that the connection will fail if the client does not have the server's certificate?

You seem to have a design flaw.
The point of a server certificate is to protect the client. If you control the client, you should use the (detected) failure to abort the connection from the client side.
If you don't control the client, but need to trust it, you need to use client certificates. These are much less common, but definitely allowed in the SSL/TLS protocol underlying HTTPS. The effect of a client certificate is reversed: when the server detects a failure with a client certificate, the server can disconnect.

Related

using c++ wss server with websocket++ or other c++ websocket lib

I am trying to write a c++ websocket server and have browser/chrome clients connect over websockets, for a multiplayer game. The websocket c++ library I'm using atm is websocketpp or websocket++. I wrote an app that allows clients to connect over ws and localhost, but when I add an ip for the address, connections don't occur at all. Now I think I have to use ssl and wss for ip connection? I tried it and there is some connection activity, but then the handshake times out. Could I be experiencing cross-orgin issues, or what, do i need ssl? I am new to websockets. Could the problem be my ssl certs I made with openssl? I can post code, or if you are familiar with a c++ library to do websockets, what is it? Is this even a possible thing to do?
There could be multiple reasons why it won't connect over ip.
The first is port forwarding. On a local network it's not necessary but running a server over a remote network, portforwarding has to be done. You can just run your server then use a simple port checker (there's many websites for them) to see if a connection can be established.
The other reason could be as you said ssl. If you are running your client on a web host, the host may require a connection to be made over ssl/wss for websockets. If your server isn't running a valid ssl certificate then this could prevent the client from connecting to your server. I know for exampe Github pages requires the server to be running wss or valid ssl certificates on the server side in order for a client connection to be established; however, if you use a custom domain name for Github pages then you can disable the need for ssl.
In order to get valid ssl certificates you would need to register a domain for your ip address then either buy certificates or use free certificates from zerossl or other distributors.
Here is a game I have written which connects to a c++ server which I'm running on my own machine with its own domain with valid ssl certificates and the client is running on github pages with a custom domain I have registered.
It's basically multiplayer minesweeper where the objective is to locate the flags rather than avoid them.

boost asio client authentication

I have a client server based c++ application which communicates over network (with boost asio) and I am planning to distribute this client application to my customers. My problem is I don't know how to prevent connection request from other applications, that is how can I make sure that only my client application is able to connect to my server. I think there is no way to do this without making the connection, than what is the best way to verify that request is coming from my client?
You can use asio's builtin SSL ability. So, you generating sertificates for each server, and client sertificates. So you can check client sertificate on server at the moment of SSL handshake. As a bonus, your traffic will be encrypted and SSL-secure. Clients can check server is not a fake; server can check clients are authorized.
Yes you have to accept the connection in order to know if it's from your application or not.
You can use a three-way handshake at the connection step:
Client connects to the server The server is sending an specific
value (integer, strings or whatever) to the new client.
The client handles this value, compute a new one with it and sends
the new value to the server.
The server checks if the returned value is correct or not.
The client will have the same compute method as the server. The others applications will not be able to use your service if they returned a bad value.

Boost ASIO with OpenSSL Can't Read HTTP Headers

I'm attempting to write a simple HTTP/HTTPS proxy using Boost ASIO. HTTP is working fine, but I'm having some issues with HTTPS. For the record this is a local proxy. Anyway so here is an example of how a transaction works with my setup.
Browser asks for Google.com
I lie to the browser and tell it to go to 127.0.0.1:443
Browser socket connects to my local server on 443I attempt to read the headers so I can do a real host lookup and open a second upstream socket so I can simply forward out the requests.
This is where things fail immediately. When I try to print out the headers of the incoming socket, it appears that they are already encrypted by the browser making the request. I thought at first that perhaps the jumbled console output was just that the headers were compressed, but after some thorough testing this is not the case.
So I'm wondering if anyone can point me in the right direction, perhaps to some reading material where I can better understand what is happening here. Why are the headers immediately encrypted before the connection to the "server" (my proxy) even completes and has a chance to communicate with the client? Is it a temp key? Do I need to ignore the initial headers and send some command back telling the client what temporary key to use or not to compress/encrypt at all? Thanks so much in advance for any help, I've been stuck on this for a while.
HTTPS passes all HTTP traffic, headers and all, over a secure SSL connection. This is by design to prevent exactly what you're trying to do which is essentially a man-in-the-middle attack. In order to succeed, you'll have to come up with a way to defeat SSL security.
One way to do this is to provide an SSL certificate that the browser will accept. There are a couple common reasons the browser complains about a certificate: (1) the certificate is not signed by an authority that the browser trusts and (2) the certificate common name (CN) does not match the URL host.
As long as you control the browser environment then (1) is easily fixed by creating your own certificate authority (CA) and installing its certificate as trusted in your operating system and/or browser. Then in your proxy you supply a certificate signed by your CA. You're basically telling the browser that it's okay to trust certificates that your proxy provides.
(2) will be more difficult because you have to supply the certificate with the correct CN before you can read the HTTP headers to determine the host the browser was trying to reach. Furthermore, unless you already know the hosts that might be requested you will have to generate (and sign) a matching certificate dynamically. Perhaps you could use a pool of IP addresses for your proxy and coordinate with your spoofing DNS service so that you know which certificate should be presented on which connection.
Generally HTTPS proxies are not a good idea. I would discourage it because you'll really be working against the grain of browser security.
I liked this book as a SSL/TLS reference. You can use a tool like OpenSSL to create and sign your own certificates.

How to debug SSL/TLS in server side

I have an application which connects to the server using ssl/tls protocol, what I want to know is in which cipher does it choses to do the handshake, my application server is on IIS win2008r2 , thou I can tell it to connect to which ever address.
I know such solution exists to check what types of ciphers the server is allowing (like sslscan, or the ssllabs website) but I need it the other way around.
Any ideas ?
You can use wireshark to look at request stream in order to see which cipher the client and server negotiated. I don't think that the handshake is encrypted at this point so you shouldn't even need to configure wireshark with the private key of the web server to decrypt the request stream.

Requirements for Successful SSL Communication

I'm using thrift to write a C++ client which will call securely to the server (which is not written by me) written in java (code generated for both server and client using same thrift files). I'm a newbie in SSL communication. For the java server side, I imported the public key certificate of client to the server truststore (server-truststore.jks) to verify the client authenticity. I exported the public certificate from the server side keystore (server.jks) and used it in the client side to authenticate the server key certificate during the SSL handshake. If I list down what I did for the SSL communication:
Server Side (java):
exported the client's public key certificate to the server's truststore
Cleint Side (C++):
Loaded the server's public certificate which was exported from the server's keystore
separately loaded the client's public key and private key (This is because I can't directly use a java key store since the client is written in c++)
All the certificates used are self signed.
So far I have been unsuccessful and got the following error continuously:
SSL_connect: certificate verify failed
I have two questions:
Is the approach I used for SSL communication correct? If not, what is the correct one?
Any possible reasons for this error?
Thank you.
Check if you can verify the key invoking directly: openssl s_client -connect serverIP:Port .
If you can is problem of your code, and for that we will need more details about it.
If not... your are not using the cert. the server is sending you, or something is wrong with the certificate.