Howto set the TLS Application Data Protocol in OpenSSL - ssl

I have added TLS encryption to one of my C++ applications using OpenSSL.
When I look at the traffic in Wireshark, I notice that you can see what kind of data is being encrypted in the "TLSv1 Record Layer: Application Data Protocol".
I don't really want to reveal this kind of information. Is there a way to set the protocol to "unspecified" or something else ?

The "Application Data Protocol" field displayed in Wireshark is a guess based on the TCP source and destination ports, and is not carried in the TLS stream.
You can check the source code of Wireshark for yourself, it is in dissect_ssl3_record(), epan/dissectors/packet-ssl.c around line 1686.

Related

Libwebsockets: keep SSL context disabled and provide one from the modem

I've recently been passed an embedded project where an MCU uses libwebsockets (version 3.1.0) to setup a websockets client. The MCU is connected to a SIMCOM modem for 4g connectivity.
Up until now the communication was non-secured: SSL context not set and modem configured to provide just a TCP link to the server. The server URI was a wss one, but security was not enforced.
I've now been asked to set the communication to use SSL/TLS with server and client authentication.
Having never used libwebsockets before and being short on time, my idea was to:
a) Leave libwebsockets set as it was, so with no SSL context set up.
b) Configure the modem to creat an SSL/TLS context and connect to the server through that one.
I did this and I can see my device sending the request to switch from http to websockets protocol, as well as the server's successful reply (code 101). But my problem is that the server's reply never gets processed by libwebsockets and the connection is dropped after a few seconds.
I can se3 that the bytes that make up the server's reply are received by the modem and passed into the MCU's buffer used to pass data into libwebsockets, but then the library never calls its net_recv method to actually read from such buffer.
Also, libwebsockets is currently built with TLS support and uses mbedTLS as SSL/TLS library. But, as said about, SSL context is currently left disabled (ssl_connection in the connection info struct is left set to 0).
So, I was wondering:
Is my approach something that can work at all? Or should I setup the SSL context from libwebsockets and let the modem setup just a TCP connection?
If I were to setup the SSL context from libwebsockets, is there a way to pass certificates and keys tot the library as just C arrays? Or do I have to have them stored as files on a filesystem and then pass their paths to the lib?
Also, I should add that the MCU has a second connection to the server, an HTTPS one, that one too setup with client and server authentication and that works with no problems at all. Therfore, I'm sure that the modem is correctly configured.
If needed, I will be able to provide more info on library configuration and used from Monday, because I'm currently travelling and don't have access to the code. But I wanted to get the ball rolling.
Thanks in advance for your help.
Yesterday, finally I had time to look at the code again. It turns out that the problem was in my code (this was always a strong possibility).
The local implementation of the net_send had a bug and returned always negative values. Thus, libwebsockets thought that the HTTP request to switch protocol had failed and hence was closing down the connection.
So, to answer the two questions above:
Yes, it's possible to setup libwebsockets to not handle SSL/TLS and then provide a SSL/TLS connection from a lower layer (the modem in my case).
It is possible to store certificates and keys in C arrays of bytes and pass them to libwebsockets if you create a custom platform implementation for your platform and create a custom implementation of POSIX like methods (open, close, read, etc).
By default the library expects to work on a POSIX like filesystem, though. So, realising a custom implementation can be a bit of a job.
The above is true for libwebsockets version 3.1.0. I haven't used any other version of the library, so things might have changed since then.
All in all, I think that configuring libwebsockets to handle SSL and the TLS handshake and then provide it with only a TCP connection is the best way of using the library.
I chose a different strategy for the wrong reasons (tight deadline + not being familiar with the codebase), but I'm definitely planning on reviewing my approach at a later date.

Use OpenSSL with a custom channel

I developed (in CPP) a unique protocol over HTTP and I use it to communicate with my server.
Now, I want to establish SSL connection over my proprietary protocol to transfer the data itself.
Can I do it using OpenSSL? I searched the web and all I found is something related with BIO, but I didn't understood how to use it for my needs..
Anyway, the best solution for me will be a way I can pass OpenSSL my proprietary send & receive functions so all the communication itself will go only through my functions.
TNX ahead :)
Use BIO pairs. You can find an example in the ssltest.c program, search the source for bio_pair. The basic idea is that you treat the OpenSSL engine as a black box.
There are four things your code has to do:
When you receive encrypted data over the connection to the other side, you have to write it to the SSL engine's encrypted BIO.
When the SSL engine wants to send encrypted data to the other side, you have to read it from the SSL engine's encrypted BIO and transport it to the other side.
When you have plaintext you want to encrypt and send, you have to write it to the SSL engine's plaintext BIO.
When the SSL engine has plaintext it has decrypted for you, you have to read it from the SSL engine's plaintext BIO.
OpenSSL acts purely as an engine following the SSL protocol and moving data between the two BIOs. It does all the protocol negotiation and operations for you, so long as you keep all four of these data streams moving.
One caution I can give you is this -- do not assume any special relationship between these things. For example, you might have some plaintext you want to encrypt and send, and when you write it to the SSL engine's plaintext BIO, the SSL engine might not be able to make forward progress until it receives some encrypted data from the other side. Treat the SSL engine as a black box and do all these four things whenever possible . Do not try to "look through" the SSL engine and, for example, expect that because you handed the SSL engine some encrypted data it will have necessarily plaintext for you. It might, but it might also need to send encrypted data to the other side.
One other caution: the SSL engine has only one state. It does not have a read state and a write state. (Search this thread for "the nightmare scenario" if you want the ugly details.) This is most likely to bite you if you use an SSL connection with multiple threads and expect it to behave just like a TCP connection (where the read and write sides are independent except in the case of a fatal error or connection close).
Second option - a protocol that has its own messages and uses HTTP to
pass them between the client and the server.
If you're using HTTP to pass your own messages, using OpenSSL for SSL/TLS would imply that you'd need to write your own HTTP library library too.
Instead, use an HTTP library that supports HTTPS (most do), via OpenSSL or not. Exchanging your custom messages on top of HTTPS should be fairly transparent and similar to using plain HTTP. You'd just need to configure HTTPS normally.

Accessing RDS With SSL - Unsupported record version Unknown-0.0

I am using Amazon RDS MySQL and connecting with SSL certificate(the default certificate available at http://s3.amazonaws.com/rds-downloads/mysql-ssl-ca-cert.pem), I am doing the following steps:
Downloaded the mysql-ssl-ca-cert.pem
Modified the above file to JKS format
And connecting from a web application through Spring - Hibernate template (org.springframework.beans.factory.config.PropertyPlaceholderConfigurer) and also use c3p0, we are setting additional URL parameter as jdbc:URL/DB?autoReconnect=true&useUniCode=true&characterEncoding=UTF-8&useSSL=true&verifyServerCertificate=false&requireSSL=true
But I am facing the below issue...
javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
How can I fix this?
Basically it means that the SSL parser is lost. The sockets layer has passed it some bytes that don't fit the SSL protocol.
When you transmit using an SSL Socket, it calls a formatting and encryption routine to create the encrypted packet. It then calls the plain sockets layer to transfer the encrypted packet to the server. The server's sockets layer receives the packet and then calls the SSL package to decrypt the packet. If the packet doesn't fit the SSL format, you get the unsupport version exception.
All bytes that arrive at the socket layer are sent to the SSL package. So the simplest way to get that error is to use the plain sockets layer to transmit a plain text message after establishing the SSL connection.
In my particular case, I ran into this error message because I was transmitting extra bytes. Let's see if I can explain my mistake clearly.
I had a buffer that was (for example) 100 bytes. I packed the buffer with my 50 byte message and called the SSL encryption routine. The resulting packet was 75 bytes long. I called send() to transmit the buffer. This was a plain sockets send; it did what I told it to do, which was transmit the entire 100 byte buffer.
At the server, the entire 100 bytes was received. The SSL package tried to decrypt the packet. It found a perfectly good SSL message packed into the first 75 bytes that were received. So far so good. Then it tried to figure out what the remaining 25 bytes meant. It assued that it was a SECOND SSL message and tried to decrypt it. That's when it choked and kicked out that nasty exception.
I hope that gives you some clues about what to look for in your code.
I found this error if I presented an unsupported client certificate. Blanking out "-Djavax.net.ssl.keyStore" and connecting with no client certificate worked.
See also http://feed.askmaclean.com/archives/secure-java-connections-by-default.html :
Support for various TLS versions differs based on the JRE version used. Make sure you know the capabilities of the JDK you are using before restricting specific TLS versions. When first running the test above, Eclipse was using JRE 1.6.0_45 instead of JRE 1.8.0_65 I expected, and was connecting using TLSv1.0 ciphers. When MySQL Server was configured to only allow TLSv1.1 and TLSv1.2, I received the following Exception:
Caused by: javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
at com.sun.net.ssl.internal.ssl.InputRecord.readV3Record(InputRecord.java:504)
Usage of older JREs should be assessed before disabling TLSv1.0 – fortunately, PERFORMANCE_SCHEMA makes it easy to survey client JREs without having to inspect every application server.

vsftpd : Make sure data transfers are encrypted?

So here is my 'problem', I set up an FTP server thanks to vsftpd so that both login & data transfers should be encrypted.
Here is the interesting part of my vsftpd.conf file.
ssl_enable=YES
allow_anon_ssl=NO
require_ssl_reuse=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=YES
ssl_sslv3=YES
rsa_cert_file=/etc/vsftpd/vsftpd.pem
rsa_private_key_file=/etc/vsftpd/vsftpd.pem
ssl_ciphers=HIGH
I am using Filezilla as an FTP client, the connection is configured like this :
Protocol : FTP - File Transfer Protocol
Encryption : Require explicit FTP over TLS
Logon type: Normal
Some things to note :
Encryption : Plain FTP : does not work and I am happy with that.
(Response: 530 Non-anonymous sessions must use encryption.)
Encryption : Require implicit FTP over TLS : does not work either, the connection is refused by the server. I guess it is because I forced the SSL connection.
Now, once the (explicit) connection is established, Filezilla is showing a small lock icon at the bottom of the window saying The connection is encrypted. Click icon for details.
I wanted to make sure that the data transfers were indeed encrypted and not plain so I captured everything on my eth. card with Wireshark while downloading a file from my server to my computer.
Except that I can not find a single packet of SSL protocol, everything is TCP.
I am out of ideas on how to make sure the data transferred is encrypted, even if filezilla says so, and each time I google "vsftpd how to make sure data transfers are encrypted", the only answers I get is "ssl_enable=YES" or "Check the box Use SSL" ...
Thank you in advance for helping me !
After a little more research and especially after following the Complete walk through on http://wiki.wireshark.org/SSL, I have a better understanding of the whole thing.
I am answering to my own question hoping this will help someone someday, as long as what follows is correct...
Also writing this down is a good way for me, I think, to see if have clearly understood my problem. Any difficulties in writing this answer will prove me wrong.
First :
Typically, SSL uses TCP as its transport protocol.
SSL is wrapped in TCP, that is why I couldn't observe explicitly the SSL protocol while capturing packets.
When analyzing a TCP packet, I could only "Follow TCP stream" but not "Follow SSL stream" which mislead me into thinking the packet was not holding encrypted data. That is funny because the observable data was not human readable ... so encrypted.
To be able to decrypt it I had to provide wireshark the encryption key :
RSA keys list
This option specifies the bindings between an IP address, a port, a protocol and a decryption key.
Then, I could observe both encrypted / unencrypted data.
Also, after reading this on http://wiki.filezilla-project.org/ :
When you apply encryption to your FTP server the CPU will have to do many calculations to encrypt the data being sent and decrypt the data being received.
I simply decided to run the UNIX top command while downloading a file. I was able to observe a high CPU usage of the filezilla client process, contrary to a unencrypted data transfer. This was a second argument that confirmed the data transfered were indeed encrypted, and thus needed to be decrypted.

Checking Encryption handshake using Wireshark for SQL connection over SSL

I have implemented a secure SSL connection on the SQL Server 2005 server. I use the "Microsoft SQL Server Management studio" to connect to the SQL Server and I check the "Encrypt Connection" check box in the options section. The connection is successful and when I look at the connection properties in the mgmt studio, it shows me "Encrypted=Yes".
So that tells me that my SSL setup is correct and I'm able to successfully connect my management studio to sql server on a secure SSL encryption channel.
Question
I want to find out what "security functions" are being used behind the scenes on this connection...because I want to make sure it complies with one of the approved standards by
fips 140-2 anex a (http://csrc.nist.gov/publications/fips/fips140-2/fips1402annexa.pdf), which has information on approved encryption functions
So I used wireshark to capture the traffic and find out the protocols/handshakes. For instance something like 'Auth TLS' request etc...
But I couldn't find out any of the encryption related information (I guess don't know how to). I don't see any SSL protocol packets. Maybe its doing all the encryption stuff at some other protocol level.
So how I do go about figuring this out? I have the packet capture from wireshark and I can provide it to whoever is interested in looking at it. stackoverflow probably doesnt allow attachments.
Any help would be appreciated.
Thanks
Amit
You want to enter ssl as the Wireshark filter to show only SSL and TLS packets, and you should see the client and server handshake and exchange a list of ciphers. If the client initiates any SSL connection, you should see a CLIENT HELLO somewhere in your capture. You can show only these packets with the filter ssl.handshake.type == 1.
That being said, running SQL Server 2005 SP1+ in FIPS 140-2 mode is covered by KB article 920995. From what you wrote, it sounds like you are just hoping the client and server pick an allowed cipher, but that's not how FIPS 140-2 works. Even if your session chooses an allowed cipher, it may not choose a FIPS-certified cipher, and the certification is what's important.
The KB article spells it out with this quote:
Note that it is not sufficient to use
an algorithm from the approved lists
in FIPS 140-2. It is necessary to use
an instance of such an algorithm that
has been certified.
To guarantee the server uses a FIPS-certified cipher, you need to enable the FIPS 140-2 policy like the KB article says.
not using wireshark but using netmon, i have a write up on doing this here:
http://cornasdf.blogspot.com/2010/04/sql-server-data-in-transit-cipher.html
Using Wireshark, you can easily find whether the connection is encrypted by looking at the packet data. This document explains the analysis clearly => https://middlewareworld.org/2020/09/04/step-by-step-ssl-handshake-with-wireshark/