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.
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:
Referencing this doc, https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites toward the top there is a note:
Once TLS v1.3 is released, there will be no workaround available for TLS v1.0 or v1.1.
Plans for TLS v1.3 include banning ciphers with known vulnerabilities from being present at any level. It is recommended to upgrade any clients using these ciphers as soon as possible or face being locked into a outdated version of Jetty, Java or even OS.
The change log for Jetty 9.4.12, includes the following:
2711 TLS 1.3 compliance
Is it confirmed that as of Jetty 9.4.12 and newer, it is no longer possible to override the default ciphers and re-enable support for TLS 1.0 and 1.1?
There is bug that Issue with default cipher excludes all about TLS1.0
: https://github.com/eclipse/jetty.project/issues/3773
private SslContextFactory(boolean trustAll, String keyStorePath)
{
setTrustAll(trustAll);
addExcludeProtocols("SSL", "SSLv2", "SSLv2Hello", "SSLv3");
setExcludeCipherSuites("^.*_(MD5|SHA|SHA1)$");
if (keyStorePath != null)
setKeyStorePath(keyStorePath);
}
The names of TLS v1.0 cipher suites are matched with above "^.*_(MD5|SHA|SHA1)$", from https://www.openssl.org/docs/man1.1.0/man1/ciphers.html
I upgraded Jetty 9.3.6 to Jetty 9.4.27 and I have a problem with SSL connection.
When I run curl on some supported operation I get
error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol (error 35) whereas when I run the same command on the server running Jetty 9.3.6 it is all working fine.
I configured jetty's newer version in the same way as was the older one (including keystore path and enabling https support). Do you have a clue what could have gone wrong during upgrade or what I could have missed?
Thanks a lot for your support.
Jetty 9.3.x and 9.4.x have different Cipher Suite exclusions.
Jetty 9.3.6.v20151106 looks like this ...
https://github.com/eclipse/jetty.project/blob/jetty-9.3.6.v20151106/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java#L248-L260
addExcludeProtocols("SSL", "SSLv2", "SSLv2Hello", "SSLv3");
setExcludeCipherSuites(
"SSL_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
Jetty 9.4.29.v20200521 looks like this ...
https://github.com/eclipse/jetty.project/blob/jetty-9.4.29.v20200521/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java#L119-L138
/**
* Default Excluded Protocols List
*/
private static final String[] DEFAULT_EXCLUDED_PROTOCOLS = {"SSL", "SSLv2", "SSLv2Hello", "SSLv3"};
/**
* Default Excluded Cipher Suite List
*/
private static final String[] DEFAULT_EXCLUDED_CIPHER_SUITES = {
// Exclude weak / insecure ciphers
"^.*_(MD5|SHA|SHA1)$",
// Exclude ciphers that don't support forward secrecy
"^TLS_RSA_.*$",
// The following exclusions are present to cleanup known bad cipher
// suites that may be accidentally included via include patterns.
// The default enabled cipher list in Java will not include these
// (but they are available in the supported list).
"^SSL_.*$",
"^.*_NULL_.*$",
"^.*_anon_.*$"
};
You'll want to evaluate why you need known vulnerable cipher suites to function.
Also, if you are using an IBM JVM all bets are off, because the IBM uses non-standard Cipher Suite names (unlike all other JVMs that use the RFC Registered Cipher Suite names).
We are using the self test suite provided by sonos (latest version from website) in order to test our service implementation. The test fails when checkiong if our server support SSL and TLS 1.0.
Failed ssl_validation test_support_tls_10 Instance Messages: Fail:
The partner must support at least one of the following cipher
suites:AES128, AES256, RC4-MD5 and RC4-SHA.The server does not support
TLS1.0 (expression is False)
Stopped ssl_validation test_support_secure_renegotiation Instance
Messages: Stop: One sessionRegegotiation element should be returned,
indicating that api.anghami.com supports secure session renegotiation
(expression is False)
Failed ssl_validation test_certificate_expiration Instance Messages:
Fail: A notBefore and notAfter element should be returned, indicating
that api.anghami.com has a date range for validity.
Stopped ssl_validation test_DNS_has_valid_x509_certificate Instance
Messages: Stop: A X.509_certificate element should be returned,
indicating that api.anghami.com has a valid X.509 certificate for the
DNS name (expression is False)
Please note that we have checked our server using:
the online certificate checking tool provided by Symantec and the results show that the certificate is valid and installed correctly and that our server clearly supports: TLS 1.2 | TLS 1.1 | TLS 1.0, along with 2 of the required ciphers (please check error message above).
In addition, test results with some screenshots and additional log files were posted on Basecamp.
Waiting for your feedback.
Regards
Based on the above your certificate is not set up for secure renegotiation and does not have a valid date range; these are both required in order for us to accept the certificate. We will follow up on basecamp.
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.