Closed michaelwildvarian closed 7 months ago
As an addendum: NIST SP 800-52 R2 clearly states that systems shall support TLS 1.3 by January 1 2024.
Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones See info in area-owners.md if you want to be subscribed.
Author: | michaelwildvarian |
---|---|
Assignees: | - |
Labels: | `area-System.Net.Security`, `untriaged` |
Milestone: | - |
This seems like it might be a question for https://github.com/dotnet/runtime. Thoughts, @CarnaViire @wfurt?
@michaelwildvarian Does chromium work on a non-FIPS-enabled Ubuntu 22.04 server?
Naively, this would be my first guess about what's going wrong: https://learn.microsoft.com/en-us/dotnet/core/extensions/sslstream-troubleshooting#client-and-server-do-not-possess-a-common-algorithm. I'd expect this to be visible in the wireshark trace.
@amcasey It also fails if Chromium is running on a non-FIPS client. But I'll check the article you linked and will get back to you.
@amcasey, doesn't look like this is the exact issue. What I see in Wireshark:
Client Hello
Hello Retry Request
Strangely, the retry request sent by the server contains the second cipher offered by the client (0x1302, TLS_AES_256_GCM_SHA384).
Change Cipher Spec
Fatal Alert (No application protocol)
If I do the same with openssl s_server
as server, the Hello Retry Request specifies TLS_AES_128_GCM_SHA256 (0x1301) instead, to which the client answers with the same Change Cipher Spec message and the s_server
then happily proceeds with the Server Hello and TLS_AES_128_GCM_SHA256 is used.
So, the problem appears to be something with to do with TLS_AES_256_GCM_SHA384. But both client and server claim support, so why does the server reject?
On request I can provide Wireshark captures via email.
@michaelwildvarian Can you send the captures to redacted (at) microsoft.com
?
Edit: removed the address now that I got the mail
This issue has been marked needs-author-action
and may be missing some important information.
I'm wondering if the issue is that we fall-back to the .NET set @rzikm https://github.com/dotnet/runtime/issues/98797#issuecomment-1964553152
@rzikm Just sent the mail.
I'm wondering if the issue is that we fall-back to the .NET set @rzikm #98797 (comment)
@wfurt, let me try this. Indeed the default /etc/ssl/openssl.cnf
does not explicitly list any ciphers, it just contains the defaults:
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
CipherString = DEFAULT:@SECLEVEL=2
I tried with replacing the cipher string with the output of openssl ciphers -s
. I also set the OPENSSL_CONF=/etc/ssl/openssl.cnf
environment variable to make sure to pick up the correct file. But no joy.
DOTNET_DEFAULT_CIPHERSTRING
This cipher list is the default for SSL_CTX_set_cipher_list
, and that OpenSSL API is only for TLS v1.2 and below.
Got it, the trigger is when server issues HelloRetryRequest (e.g. when client does not use preferred group in key_share), when we attempt to do ALPN negotiation the second time, the list of ALPNs is no longer there
We should look at it in 9.0 timeframe.
Many thanks for the analysis. Is this something we can work around?
It is possible to tweak the server preferred groups via openssl.cnf
[openssl_init]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
Groups =
Not sure what the best value for the Groups field is, Chrome is attempting x25519
, your server wants secp256r1
, so it should probably include both of those (e.g. x25519:secp256r1
), or perhaps x25519:DEFAULT
.
This will make server accept the curve and not issue HelloRetryRequest, but perhaps there is a reason why x25519 is not accepted when fips-preview is applied. I defer to @bartonjs and @vcsjones's judgement as to what is a good setting here.
there is a reason why x25519 is not accepted when fips-preview is applied
X25519 is not a FIPS approved algorithm. When you run in FIPS mode, the algorithm gets turned off.
From FIPS 140-3-IG:
The publication of SP 800-186 does not impact the curves permitted under SP 800-56Arev3. Curves that are included in SP 800-186 but not included in SP 800-56Arev3 are not approved for key agreement. E.g., the ECDH X25519 and X448 key agreement schemes (defined in RFC 7748) that use Curve25519 and Curve448, respectively, are not compliant to SP 800-56Arev3.
Reopening for backport consideration.
@michaelwildvarian does this issue prevent you from migrating to .NET8? It makes it easier for us to get the servicing approved if we have business justification.
@rzikm , we are already on .NET8 but have design freeze somewhere in April, early May. So far we have TLS 1.3 disabled (by configuration), but it would be great to release the product with TLS 1.3 support, so we don't have to do a patch release before it even hits the market.
I see, and FIPS is somehow required for your scenario?
In case you don't want to disclose something publicly here at GitHub, you can contact me privately at radekzikmund [at] microsoft.com.
@rzikm the issue also affects us (we had duplicate issue dotnet/aspnetcore/54366 raised) and is preventing us fully rolling out a firm-wide .NET 8 base image.
Our enterprise runs OpenShift clusters that have FIPS mandated for all accounts, so anyone running the image would have to follow the workaround.
@KenMcC98 just to point out (and be a stickler...): The workaround breaks FIPS compliance, so it really isn't one.
@rzikm many thanks for getting the fix into the 8.0.5 milestone! 🙏
Fixed in main (9.0) in PR #99357 and in 8.0.5 in PR #99670.
Is there an existing issue for this?
Describe the bug
When Kestrel is running on a FIPS-enabled Ubuntu 22.04, TLS 1.3 negotiation fails for Chromium browsers and
ERR_SSL_PROTOCOL_ERROR
is displayed.Scenarios tested:
Expected Behavior
Chromium based browsers should be able to establish a TLS 1.3 session with Kestrel servers running on FIPS-enabled Ubuntu 22.04.
Steps To Reproduce
sudo pro attach --no-auto-enable <token>
sudo pro enable fips-preview --assume-yes
sudo reboot
cat /proc/sys/crypto/fips_enabled
<-- Ensure the output is1
sudo apt install ssl-cert
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install dotnet-sdk-8.0
sudo bash -c 'echo some.host.internal > /etc/hostname
sudo bash -c 'echo "127.0.0.1 some.host.internal" >> /etc/hosts
sudo make-ssl-cert generate-default-snakeoil --force-overwrite
mkdir app
cd app
dotnet new webapi -au None
appsetting.Development.json
Urls = https://127.0.0.1:4445
Kestrel:Certificates:Default:Path = /etc/ssl/certs/ssl-cert-snakeoil.pem
Kestrel:Certificates:Default:KeyPath = /etc/ssl/private/ssl-cert-snakeoil.key
Logging:LogLevel:Microsoft.AspeNetCore.HttpLogging.HttpLoggingMiddleware = Trace
Logging:LogLevel:Microsoft.AspeNetCore.Server.Kestrel = Trace
dotnet build
sudo dotnet run --no-build
https://some.host.internal:4445/weatherforecast
. It should display the following:Kestrel:EndpointDefaults:SslProtocols = [ "Tls12" ]
toappsettings.Developmen.json
openssl s_server
is able to successfully negotiate TLS 1.3 with Chrome:sudo openssl s_server -key /etc/ssl/private/ssl-cert-snakeoil.key -cert /etc/ssl/certs/ssl-cert-snakeoil.pem -accept 4446 -www
Exceptions (if any)
.NET Version
8.0.200
Anything else?
Output of
dotnet --info
:On request I can provide Wireshark captures via email.