Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HttpClient: Add API to change cipher suites offered in SSL/TLS handshake #22507

Closed
mattzink opened this issue Jun 26, 2017 · 25 comments
Closed
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Net.Http
Milestone

Comments

@mattzink
Copy link

Depends on SslStream API proposal: dotnet/corefx#24588

Re-opening a previously closed issue (https://github.com/dotnet/corefx/issues/15157) with a supporting use case.

For US government compliance (FIPS, CNSA, etc), the set of allowed ciphers over TLS is mandated. There does not seem to be any mechanism for .NET Core on Linux to adjust the cipher suite offered when using HttpClient and friends, and therefore .NET Core cannot currently be used in most government installations. This is a key blocker to adoption for us.

[EDIT] Add dependency on SslStream issue by @karelz

@CIPop
Copy link
Member

CIPop commented Jul 7, 2017

On Windows this is achievable via system-wide registry key changes: https://technet.microsoft.com/en-us/library/dn786418(v=ws.11).aspx#BKMK_SchannelTR_CipherSuites

@mattzink
Copy link
Author

It should be configurable per connection, just like how the protocol level now is (Http​Client​Handler.​Ssl​Protocols). I would expect a Http​Client​Handler.​Ssl​CipherSuites property to exist and work across all supported platforms

@Drawaes
Copy link
Contributor

Drawaes commented Aug 14, 2017

This is not just an issue on Linux. We want to say that our webserver only uses the following secure ciphers (say ECDHE + AES + GCM) but then sometimes we have to connect to older less secure services with Http client from these webservers. We are forced to make a "global" configuration and therefore drop to the lowest common denominator out of all the other services we call. This is not just a problem for Government but Finance, and I imagine a number of other industries.

@grzegorz-ogrodowski
Copy link

Hello,
any news about this topic?
Are that changes included in dotnet/corefx#24389?
It will be really helpful to change cipher suit per connection.

@Drawaes
Copy link
Contributor

Drawaes commented Oct 9, 2017

That PR doesn't address it at all. This will require an API review so someone will need to launch it.

@grzegorz-ogrodowski
Copy link

Thank for quick answer.
So let to be clear - At this time API is waiting for review before any development process?
Or someone should propose API changes?

@Drawaes
Copy link
Contributor

Drawaes commented Oct 9, 2017

Someone needs to propose an API ....

@Drawaes
Copy link
Contributor

Drawaes commented Oct 9, 2017

I am happy to do it if you don't want to...

@grzegorz-ogrodowski
Copy link

I can do it, however - I did not do this ever.
You can do it quicker or better.

@PeterSmithRedmond
Copy link

NIST guidelines allow quite a number of potential cipher suites. It seems bad to only let people pick one (because then they can only connect to servers that support that particular suite), but it also seems bad to make people specify a large list.

How about something simpler: on the HttpClientHandler add a ".RequireStrongCrypto". On Windows, this would turn on the strong crypto in the SChannel layer, and that should be FIPS compliant. And as time goes by, the OS can evolve the set of strong crypto and keep our customer secure.

If we want to be bold about security, we can have this value TRUE by default. That protects our users by default (which is good) and the inconvenience that some developers need to connect to weak servers (and there will be servers that start out strong, but over time are deemed weak)

@Drawaes
Copy link
Contributor

Drawaes commented Oct 10, 2017

Alternatively you could do what I did in my demo .net managed tls lib. Have the ability to supply a list for those that want to and know what they're doing.

Reasoning... I have current places of employment that have a specific list of allowed protocols that aren't FIPS based ( not everyone is in the US) but then have some precanned lists ... FIPS could be one, but these should be included

https://wiki.mozilla.org/Security/Server_Side_TLS

As they are pretty well regarded in industry and include a low medium and high (effectively) setting.

@PeterSmithRedmond
Copy link

Converting your comments into a full API, is the below roughly what you're looking for? Ignore all of the obvious errors, spelling mistakes and syntax issues, please :-)

class HttpClientHandler
{
public property IList AllowedCipherSuites {get; set;}
}

class SslStream
{
public property IList AllowedCipherSuites {get; set;}
}

class CipherSuites
{
// Individual named sets of values
static CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CGM_SHA256 = { IndividualSettings, RsaKeyX, Aes128, Sha256 };

// Common lists of values from different sources
static List<CipherSuite> FipsCipherSuite2017 = { ... };
static list <CipherSuite> MozillaModernCipherSuite = { ... }
static list <CipherSuite> MozillaIntermediateCipherSuite = { ... }
 [deprecated]
static list <CipherSuite> MozillaOldCipherSuite = { ... }
static list<CipherSuite> OSStrongCipherSuite = { ... } // uses a special indicator that will
      // enable, e.g., the Windows STRONG_CRYPTO flag.

}

class CipherSuite
{
enum CipherSuiteType { OsStrong, IndividualSettings }
public ExchangeAlgorithmType { get; set; } // e.g. RsaKeyX
public CipherAlgorithmType {get; set;} // e.g. Aes128
public HashAlgorithmType { get; set; } // e.g. Sha256
// From namespace system.security.authentication
}

And then to use this the end developer does something like this:
var handler = new HttpBaseHandler ();
handler.AllowedCipherSuites = CipherSuites.FipsCipherSuite2017;

@Drawaes
Copy link
Contributor

Drawaes commented Oct 11, 2017

That way you can lead the dev by the nose and help them with the classic "Pit of success". As someone who often advises other teams (infact just this week) on what ciphers to enable/disable it would be great to just say, look you use websockets, all your clients have to have a modern browser to use it turn on MozillaModernCipherSuite... :)

@mattzink
Copy link
Author

As long as users are able to construct their own CipherSuite instances, and are not just limited to the pre-canned ones, then I think something along the lines of Peter's proposal would meet our specific needs.

Another tricky aspect will be defining the set of cross-platform (SChannel, OpenSSL, etc) cipher types (I think CipherAlgorithmType in the proposal), and again supporting custom user provided instances (for custom OpenSSL builds with new ciphers, etc)

@davidsh
Copy link
Contributor

davidsh commented Oct 11, 2017

SslStream part is being tracked in dotnet/corefx#24588

@karelz
Copy link
Member

karelz commented Nov 30, 2017

Duplicate of dotnet/corefx#24588 ... closing.

@karelz karelz closed this as completed Nov 30, 2017
@mattzink
Copy link
Author

mattzink commented Dec 1, 2017

@karelz This defect is about adding protocol selection to HttpClient. https://github.com/dotnet/corefx/issues/24588 is about adding it to SSLStream, which may be a prerequisite to getting it into HttpClient, but I don't think obviates the need for this issue.

@karelz
Copy link
Member

karelz commented Dec 1, 2017

I see, it was incorrectly labeled (both area and issue type) and the title isn't super clear. Reopening.
We need official API proposal next.

@karelz karelz reopened this Dec 1, 2017
@karelz karelz changed the title Allow changing cipher suites offered in SSL/TLS handshake HttpClient: Add API to change cipher suites offered in SSL/TLS handshake Dec 1, 2017
@mattzink
Copy link
Author

mattzink commented Dec 1, 2017

The API proposal would depend very much on the final API that's used in SSLStream, so I'll hold off until that is settled.

@Priya91
Copy link
Contributor

Priya91 commented Dec 8, 2017

Adding ciphersuite property to sslstream is not a pre-requisite for this issue, the underlying implementations don't use SslStream .NET class for making secure connections. Only ManagedHandler depends on that, the curlhandler and WinhttpHandlers should be configuration through libcurl and winhttpapi support. This api proposal can happen independently from sslstream proposal.

@mattzink
Copy link
Author

mattzink commented Jan 4, 2018

@Priya91 What I meant was that while the implementation isn't dependent on SslStream, the APIs exposed for cipher customization should be identical to what's being discussed in https://github.com/dotnet/corefx/issues/24588.

@krwq
Copy link
Member

krwq commented Apr 13, 2019

We have just merged support for changing cipher suites in SslStream: https://github.com/dotnet/corefx/issues/24588 - currently Linux with OpenSsl 1.1.1 is or OSX is required.

@stephentoub
Copy link
Member

This is available via SocketsHttpHandler.SslOptions.CipherSuitesPolicy.

@ghost
Copy link

ghost commented Nov 21, 2019

@stephentoub I think I must be missing something with that API. The following code enables 1 cipher suite, yet the result in wireshark TLS1.3 ClientHello lists 31 cipher suites (of which TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 is indeed one, but that is beside the question)

            var sslOptions = new SslClientAuthenticationOptions {
                CipherSuitesPolicy  = new CipherSuitesPolicy(new List<TlsCipherSuite>{ TlsCipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 })
            };
            var socketsHttpHandler = new SocketsHttpHandler { SslOptions = sslOptions };
            var httpClient = new HttpClient(socketsHttpHandler, true);
            httpClient.GetAsync("https://www.google.com").Wait();

Edit: .NET Core SDK | Version: 3.0.100 | 04339c3a26

@krwq
Copy link
Member

krwq commented Nov 21, 2019

@tick-rick what OS are you running on? Can you file a separate issue on that? (please share dotnet --info output)

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Net.Http
Projects
None yet
Development

No branches or pull requests