I have the following source to connect websocket server using TLS/SSL protocol :
struct sessionTLS {
int sid;
SSL_CTX *ctx;
SSL *ssl;
};
sessionTLS tls ;
tls.ctx = SSL_CTX_new(TLS_client_method());
According to libressl manual : https://man.openbsd.org/SSL_CTX_new.3
TLS_method(), TLS_server_method(), TLS_client_method()
These are the general-purpose version-flexible SSL/TLS methods.
The actual protocol version used will be negotiated to the highest version
mutually supported by the client and the server. The supported protocols are
TLSv1, TLSv1.1, TLSv1.2, and TLSv1.3. Applications should use these methods
and avoid the version-specific methods described below.
Then I like to know how to know the actual protocol is ?! after negotiation done between server and client , there should be some messages showes like SSLV3 is the protocol, TLSV1 is the protocol, or else .
I am brand new in TLS/SSL, any suggestions, informations are great appreciated .
Related
I am confused about which TLS version is used, when inspecting packets in Wireshark.
In the Client Hello package it says "TLSv1.3 Record Layer", the version beneath says "TLS 1.0" and for the Handshake Protocol it says "Version: TLS 1.2".
Because RFC 8446 descirbed:
struct {
ProtocolVersion legacy_version = 0x0303; /* TLS v1.2 */
Random random;
opaque legacy_session_id<0..32>;
CipherSuite cipher_suites<2..2^16-2>;
opaque legacy_compression_methods<1..2^8-1>;
Extension extensions<8..2^16-1>;
} ClientHello;
The client must use 0x0303 (TLS 1.2) to make TLS 1.3 handshake successfully when some interval server did not implement TLS version negotiation correctly.
Instead, we use supported_versions in the Extension to tell the server that the client can support the TLS 1.3:
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.
I am trying to connect to a web service which is written in Java language on the server side. My program is written in VB.NET 4.0 on the client side.
When i try to call any methods from the web service I receive the following error message :
WS-Metadata Exchange Error URI: [http://...] Metadata contains a reference that cannot be resolved. The request was aborted: Could not create SSL/TLS secure channel
I am using a certificate to connect to the web service, however it seems that the problem is on the communication level between my host machine (client) and the server. The certificate i am using is never been checked as the client and the server can even not communicate.
I have tried to set the security protocol to "SSLv3" or "TLS12" but it didn't help. Thank you in advance for any suggestions.
Also i should mention that i managed to connect to this web service using a Java class. It seems that when the client side is written in Java it works but when it's in VB.NET it doesn't work.
P. HAB
EDITED :
I used "Wireshark" to discover the HTTPS packets which are sent and received by my program, here what I found in the transmitted packets :
Request by the client :
Secure Sockets Layer
TLSv1 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 140
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 136
Version: TLS 1.0 (0x0301)
Random
Session ID Length: 0
Cipher Suites Length: 24
Cipher Suites (12 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 71
Extension: server_name
Extension: elliptic_curves
Extension: ec_point_formats
Extension: Extended Master Secret
Extension: renegotiation_info
Response from the server :
Secure Sockets Layer
TLSv1 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
Content Type: Alert (21)
Version: TLS 1.0 (0x0301)
Length: 2
Alert Message
Level: Fatal (2)
Description: Handshake Failure (40)
I have tried to change the security protocol to different versions of SSL/TLS but it changed nothing. My client tries to send a "Client hello" with standard values (no user-customized parameters were specified) but the server is not accepting it. Any suggestions ?
Solution found :
The problem is in fact related to the Cipher suites and specially the RC4 algorithme. Actually my client is written in VB.NET 4.0 and in this version of .NET the deprecated RC4 algorithme is still supported and proposed by the .NET framework to any Web server during the "Hello Client" (Handshake) process.
The only presence of the RC4 cipher suites in the supported list of the cipher suites by my client was making the server to abort the connection with the following error message : "The request was aborted: Could not create SSL/TLS secure channel"
So I had to deactivate the RC4 cipher suites on my client machine by going in the system registry using regedit.exe and add the following key to these two specified paths :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319
"SchUseStrongCrypto"=dword:00000001
And
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319
"SchUseStrongCrypto"=dword:00000001
After restarting the client machine I was able to connect to the web service succesfully.
For more information about the deprecated RC4 algorithmes :
https://technet.microsoft.com/en-us/library/security/2960358.aspx
=> Also you should notice that this problem exists only in .NET 4.0-4.5. From the version 4.6 and above its working fine.
I'm currently using the following listen and serve command to run a secure websocket/file server:
http.ListenAndServeTLS(":443", "site.crt","site.key", router)
However, I want to set the cipher to TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 and also set a min SSL/TLS version.
How can I do this?
I think I need to use this Config structure somehow, but I'm not sure how to do this.
2015: You can see an example in secrpc/tls_server.go:
tls.Listen("tcp", addr, &tls.Config{
Certificates: []tls.Certificate{cert},
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
},
MinVersion: tls.VersionTLS12,
PreferServerCipherSuites: true,
})
See also go/issues/11047 for an example using ListenAndServeTLS: once you have defined your Config, you define your server:
server := &http.Server{Addr: ":4000", Handler: nil, TLSConfig: config}
server.L
In 2021, you also have "Automatic cipher suite ordering in crypto/tls" from Filippo Valsorda:
Go 1.17, recently released, takes over cipher suite preference ordering for all Go users.
While Config.CipherSuites still controls which TLS 1.0–1.2 cipher suites are enabled, it is not used for ordering, and Config.PreferServerCipherSuites is now ignored.
Instead, crypto/tls makes all ordering decisions, based on the available cipher suites, the local hardware, and the inferred remote hardware capabilities.
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.