Not possible to accept only TLS 1.2 with boost::asio? - ssl

So I am trying to modify a third party (libtorrent) to only accept the TLS 1.2 protocol.
Part of the setup of the SSL context:
boost::shared_ptr<context> ctx = boost::make_shared<context>(boost::ref(m_ses.get_io_service()), context::tlsv12)
ctx->set_options(context::default_workarounds
| boost::asio::ssl::context::no_sslv2
| boost::asio::ssl::context::no_sslv3
| boost::asio::ssl::context::no_tlsv1
| boost::asio::ssl::context::no_tlsv1_1
| boost::asio::ssl::context::single_dh_use);
However when I am testing my connection with OpenSSL s_client it still seems to accept tls 1.0 and tls 1.1 connection.
Is there something I am doing wrong?
EDIT: Added "| boost::asio::ssl::context::no_tlsv1_1" to options. I realized I was referring to an old boost reference guide. It did however not change anything.
EDIT: I just realize that I have not mentioned that this connection is a two-way/mutual authentication connection. Not sure if that changes anything.

There is no constant for TLS1.2 in asio::ssl::context. But you can use native openssl API to do that:
#include <openssl/ssl.h>
long ssl_disallowed = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
ssl_disallowed &= ~SSL_OP_NO_TLSv1_2;
SSL_CTX_set_options(ctx.native_handle(), ssl_disallowed);

This is a total shot in the dark, but try this:
Try creating a string of ciphers specific to TLS 1.2 and then call
char* TLS_12_CIPHERS = "... list of ciphers specific to TLS 1.2";
SSL_CTX_set_cipher_list(ctx->native_handle(), TLS_12_CIPHERS);
Then set the option on the context (assuming it's a server context) that the server gets to choose what ciphers it wants use, not client.
SSL_CTX_set_options(ctx->native_handle(), SSL_OP_CIPHER_SERVER_PREFERENCE);
You'd think that boost::asio::ssl would take care of this stuff for you by specifying the no_X options but I can't be sure. Like I said this is a shot in the dark, but explicitly configuring context using the OpenSSL API in this way should enforce the conditions you're after. Even if somewhere, somehow, some conflicting option is being set to allow non TLS 1.2 connections, with these options, any non TLS 1.2 connection will fail with the error "no shared cipher".
As for why your server is even advertising that non 1.2 connections are acceptable is unknown, but one possible explanation is that there is a default context that is advertising this. This is why sehe made the point about "applying to all connections."
Here is a list of TLS 1.2 specific ciphers.

Related

Unable to decrypt TLS 1.3 packets with the keys got using SSL_CTX_set_keylog_callback openssl API in Wireshark

I'm working on a task where i need to decrypt all the TLS 1.3 encrypted packets in wireshark (using Edit->Preferences->Protocol->TLS->pre-Master_secret log filename option) for debugging purpose. so i stored all the keys of TLS 1.3 sessions by setting the call back function with openssl provided API() call back function into a file as shown below:
SSL_CTX_set_keylog_callback(pCtx_m,Keylog_cb_func);
void Keylog_cb_func(const SSL *ssl, const char *line) {
// Code to log the line into a file in append mode
}
With this, i'm able to decrypt the TLS 1.3 packets with the keys logged into the file for only the below three ciphers in wireshark
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
and the other two ciphers of TLS1.3 TLS_AES_128_CCM_8_SHA256 , TLS_AES_128_CCM_SHA256 is not getting decrypted using the keys (in wireshark) opensll API has given though the calls are established over these two ciphers successfully.
I have read this post in stackoverflow about the default enabled cipher suite but i'm not quite sure about if this issue is something related to that. Could anyone help me to understand what i'm doing wrong here:
Sample Key File:
SERVER_HANDSHAKE_TRAFFIC_SECRET dd228de6d3f32ae5d83a9009c2e5908cb71c16d8624f5930dd05cabea3b7cc63 aa48ffe195090f87138caf32a520ecd41644f23f6d778f6436b5e2d697452572
CLIENT_HANDSHAKE_TRAFFIC_SECRET dd228de6d3f32ae5d83a9009c2e5908cb71c16d8624f5930dd05cabea3b7cc63 415e363721b8e204d3e2a2f94682d25792f565770a0f9221e86738d1c540e21b
EXPORTER_SECRET dd228de6d3f32ae5d83a9009c2e5908cb71c16d8624f5930dd05cabea3b7cc63 25276ba5f066f69b6caac00d35e981ff0b7d70e20d541c9435538d32a640ecdc
SERVER_TRAFFIC_SECRET_0 dd228de6d3f32ae5d83a9009c2e5908cb71c16d8624f5930dd05cabea3b7cc63 9d683bacbb0ce07fa5d0425c2763920f11d98af85c7461a52e26efb6bdaf74b5
CLIENT_TRAFFIC_SECRET_0 dd228de6d3f32ae5d83a9009c2e5908cb71c16d8624f5930dd05cabea3b7cc63 bfca7bc330de3836b0e49619375b504f4d2794206c4ecc7fcd1dfdab363bd36a
SERVER_HANDSHAKE_TRAFFIC_SECRET cb2136f271de0e168eb92a9f2a6811c76fe87d08c9b4ae374f4efc72ccdc7ea5 1be3cc095c1e336168ab10619c266eaf7a9057edf724d65f3016ba64d642ab0f
EXPORTER_SECRET cb2136f271de0e168eb92a9f2a6811c76fe87d08c9b4ae374f4efc72ccdc7ea5 0cfa53e94a8a6cf085af19a45a062152299b5ccea84cbffe237f136f0854672e
SERVER_TRAFFIC_SECRET_0 cb2136f271de0e168eb92a9f2a6811c76fe87d08c9b4ae374f4efc72ccdc7ea5 7de206865a34e1b3b004d47075d534ebfd60b47a16ce525f3c0da47c9c78c57f
CLIENT_HANDSHAKE_TRAFFIC_SECRET cb2136f271de0e168eb92a9f2a6811c76fe87d08c9b4ae374f4efc72ccdc7ea5 1a4cad91d84607f44cd6a65cf1e9bcddaf3488d2dcb67b5246995485226dfa5c
CLIENT_TRAFFIC_SECRET_0 cb2136f271de0e168eb92a9f2a6811c76fe87d08c9b4ae374f4efc72ccdc7ea5 be0df5b77fb5edb1785118e6adb119a5820beacb74d01d8cdee344d3feb56488
Wireshark Version: Version 3.6.1 (v3.6.1-0-ga0a473c7c1ba).
Thanks in advance
Prakash
It's found that wireshark Version 3.6.7 (v3.6.7-0-g4a304d7ec222) itself currently has an issue in the TLS 1.3 packet decryption feature for these two ciphers (LS1.3 TLS_AES_128_CCM_8_SHA256 , TLS_AES_128_CCM_SHA256 ) due to invalid-aad-length, and the same would be fixed in the upcoming version. We have reported a bug to the wirshark forum as in the link below
https://gitlab.com/wireshark/wireshark/-/issues/18277

go-swagger TLS Config

I generated a golang server with go-swagger. I set the scheme to https (and only https). When I startup my server I get a TLS error.
the required flags `--tls-certificate` and `--tls-key` were not specified
It is clear that I haven't properly set my TLS flags but I really don't know the best way to to do this in go with go-swagger.
Anyone have any experience setting up TLS with go-swagger as I couldn't find any good links?
Thank you.
When you get certificates you get a private key file and a public key (certificate) file.
Here's an example of how they are used: https://github.com/go-swagger/go-swagger/tree/master/examples/todo-list#run-full-server
./todo-list-server --tls-certificate mycert1.crt --tls-key mycert1.key

ssl version and cipher suites of the client

I'm working on a soap server, that will serve some old embedded computers with an legacy soap protocol.
I write it in go and so far used just plain http, but in production it must use ssl encryption. So I've just created a key and a cert (from this site) and used the http.ListenAndServeTLS function.
But now the computers cannot connect and the server is just printing a handshake error:
server.go:2848: http: TLS handshake error from [::1]:38790: tls: no cipher suite supported by both client and server
In the docs, for the computers, isn't the supported ssl version or the ciphers. So I wanted to know, how to find out the client's ssl version, and also the available cipher suites that the client supports.
And then how can I configure the golang http server so it will support the selected ciphers.
There seems to be two questions here, so let's do this in two parts:
Finding the client's TLS version and supported cipher suites:
To do this, you need to set the GetConfigForClient field of the tls.Config object.
This field takes a method with signature:
func(*ClientHelloInfo) (*Config, error)
It is called on receipt of a Client Hello message with a ClientHelloInfo struct. This struct contains the following fields of interest to you:
// CipherSuites lists the CipherSuites supported by the client (e.g.
// TLS_RSA_WITH_RC4_128_SHA).
CipherSuites []uint16
// SupportedVersions lists the TLS versions supported by the client.
// For TLS versions less than 1.3, this is extrapolated from the max
// version advertised by the client, so values other than the greatest
// might be rejected if used.
SupportedVersions []uint16
Please read the comments around GetConfigForClient and ClientHelloInfo for exactly how GetConfigForClient should behave, and for field details.
Specifying server-supported version and cipher suites:
This is also done through the tls.Config object using the following fields:
// CipherSuites is a list of supported cipher suites. If CipherSuites
// is nil, TLS uses a list of suites supported by the implementation.
CipherSuites []uint16
// MinVersion contains the minimum SSL/TLS version that is acceptable.
// If zero, then TLS 1.0 is taken as the minimum.
MinVersion uint16
// MaxVersion contains the maximum SSL/TLS version that is acceptable.
// If zero, then the maximum version supported by this package is used,
// which is currently TLS 1.2.
MaxVersion uint16
For example, you could set your tls.Config with the following fields:
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
etc...
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
},
MinVersion: tls.VersionTLS12,
The full list of supported cipher suites is in the tls docs.

Find SSL Version after Handshake in OpenSSL

I want to find out the protocols supported by a target but the problem is that their are quite a number websites which are not supporting a particular version but when i performed handshake it was successful becz target surpassed the version that i gave and perform handshake on the supported version
[ it happened on only 1 website]
example : i passed a version :TLSVersion.TLS_1_2 but the handshake is performed using TLSv1_0 becz it is not supporting TLSVersion.TLS_1_2
Because of the above issue i want to check the version on handshake and i dont want to use scapy.ssl_tls
version = [SSL.SSLv23_METHOD,
SSL.TLSv1_METHOD,
SSL.TLSv1_1_METHOD,
SSL.TLSv1_2_METHOD]
context = OpenSSL.SSL.Context(version)
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.settimeout(CONNECTION_TIMEOUT)
connection = OpenSSL.SSL.Connection(context,soc)
connection.connect((host,port))
connection.do_handshake()
#wants to check version here
i want to check the version on handshake
The relevant functions to check the version both client and server use for the remaining session in pyOpenSSL are get_protocol_version_name or get_protocol_version:
connection.do_handshake()
#wants to check version here
print(connection.get_protocol_version_name())
Note that these functions are only available since pyOpenSSL 0.16.0
Please not also that you cannot specify a list of TLS methods when creating the context but only a single method which essentially specifies the minimal TLS version supported by the client. Thus
context = OpenSSL.SSL.Context(SSL.TLSv1_METHOD)
allows the client to use TLS 1.0 and better. If you instead use SSL.TLSv1_2_METHOD the client would be restricted to TLS 1.2 and better and thus could not establish a SSL connection with a server supporting only TLS 1.0.
Find SSL Version after Handshake in OpenSSL...
If I am parsing what you want correctly... you want the protocol version like printed by openssl s_client:
$ openssl version
OpenSSL 1.1.0b 26 Sep 2016
$ openssl s_client -connect www.google.com:443 -servername www.google.com
CONNECTED(00000005)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
Server did acknowledge servername extension.
---
...
---
New, TLSv1.2, Cipher is ECDHE-RSA-CHACHA20-POLY1305
Server public key is 2048 bit
Secure Renegotiation IS supported
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
...
The first message of "New, TLSv1.2" tells you about the cipher. That is, when is ECDHE-RSA-CHACHA20-POLY1305 first arrived in TLS. In the case of ECDHE-RSA-CHACHA20-POLY1305, the cipher suite was first seen in TLS 1.2.
The source code for s_client is located at <openssl src>/apps/s_client.c. The code responsible in OpenSSL 1.0.2 is around line 2210:
/* line 2210 */
c = SSL_get_current_cipher(s);
BIO_printf(bio, "%s, Cipher is %s\n",
SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
...
The second message of "Protocol: TLSv1.2" tells you the protocol version used during key exchange and subsequent cipher selection and bulk transfer.
The code responsible in OpenSSL 1.0.2 is <openssl src>/ssl/ssl_txt.c around line 105:
/* line 105 */
int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
{
unsigned int i;
const char *s;
if (x == NULL)
goto err;
if (BIO_puts(bp, "SSL-Session:\n") <= 0)
goto err;
if (x->ssl_version == SSL2_VERSION)
s = "SSLv2";
else if (x->ssl_version == SSL3_VERSION)
s = "SSLv3";
else if (x->ssl_version == TLS1_2_VERSION)
s = "TLSv1.2";
else if (x->ssl_version == TLS1_1_VERSION)
s = "TLSv1.1";
else if (x->ssl_version == TLS1_VERSION)
s = "TLSv1";
else if (x->ssl_version == DTLS1_VERSION)
s = "DTLSv1";
else if (x->ssl_version == DTLS1_2_VERSION)
s = "DTLSv1.2";
else if (x->ssl_version == DTLS1_BAD_VER)
s = "DTLSv1-bad";
else
s = "unknown";
if (BIO_printf(bp, " Protocol : %s\n", s) <= 0)
goto err;
...
}
I want to find out the protocols supported by a target but the problem is that their are quite a number websites which are not supporting a particular version but when i performed handshake ...
This is a different problem. You should look at the source code for sslscan at SSLScan - Fast SSL Scanner to see how it works. The Sourceforge one seems abandoned. It lacks SNI and other new features, like secure negotiation and ALPN.
You might try this sslscan from GitHub: rbsec/sslscan. The GitHub one is actively maintained and seems to be more up to date.
example : i passed a version :TLSVersion.TLS_1_2 but the handshake is performed using TLSv1_0 becz it is not supporting TLSVersion.TLS_1_2
This will not happen. TLS specifies one protocol version only. The idea is your try TLS 1.2. If it fails, then you fall back to TLS 1.1. If it fails, then you fall back to TLS 1.0. Ad infinitum.
The try-and-fallback approach is the reason for RFC 7504, TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks. This was an awful band-aide from the Browser crowd. See, for example, Last Call: <draft-ietf-tls-downgrade-scsv-03.txt> (TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks) to Proposed Standard.
TLS does not accept a range of protocol versions like many folks think. We have tried to get it changed a few times. See, for example, A new TLS version negotiation mechanism.

How to disable SSL and switch to TLS for Openssl on fedora?

I am trying to block SSL as a measure against Poodle vulnerability.
Is it possible to alter the ciphers list rather than do something to disable the SSL compatibility and switch to TLS???
Individual servers must be configured to disable SSL and use TLS exclusively - it is not a system-wide configuration.
I expect that most software in the official Fedora channels will have been updated to disable SSL where possible, but you will need to check that the server software you are using is configured appropriately.
How to disable SSL and switch to TLS for Openssl on fedora?
For OpenSSL, the answer is platform agnostic.
To disable SSL and only allow TLS, perform the following:
const SSL_METHOD* method = SSLv23_method();
if(NULL == method) handleFailure();
SSL_CTX* ctx = SSL_CTX_new(method);
if(NULL == ctx) handleFailure();
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
SSL_CTX_set_options(ctx, flags);
/* No error code returned */
The SSLv23_method says "give me SSLv2 and above". You then remove the unwanted SSLv2 and SSLv3 protocols with SSL_CTX_set_options.
You should also call SSL_set_cipher_list to set your preferred cipher list. Something like:
const char* const PREFERRED_CIPHERS = "HIGH:!aNULL:!kRSA:!PSK:!SRP!MD5:!RC4";
res = SSL_CTX_set_cipher_list(ctx, PREFERRED_CIPHERS);
if(1 != res) handleFailure();
IF you control both the client and server, then only use TLS 1.2 and the AES/GCM and Camellia/GCM cipher suites. If you are interacting with compatible servers, then ChaCha20 is OK, too; but its not available everywhere (see, for example, ChaCha20 and Poly1305 based Cipher Suites for TLS
).
The GCM cipher suites (and the ChaCha20 stream cipher) avoid some bugs built into the protocol at the architectural level. They are the cause of the padding attacks.
Is it possible to alter the ciphers list rather than do something to disable the SSL compatibility and switch to TLS???
No. Protocols and cipher suites are two different things. You have to address them in turn.