镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

SslStream client on Linux incorrectly reports that it is mutually authenticated #40314

Closed

Description

@smbz

Description

When using SslStream.AuthenticateAsClient with a client certificate, IsMutuallyAuthenticated is set to true even if the server did not request a client certificate and the client didn't send one. It should be false, as the client has not authenticated itself to the server (which is the behaviour on Windows).

I've written a short demo program: smbz/IsMutuallyAuthenticatedDemo. Just so it's here, the core is:

string host = "www.microsoft.com";
TcpClient client = new TcpClient(host, 443);

SslStream stream = new SslStream(client.GetStream());
stream.AuthenticateAsClient(host, clientCertificateCollection, SslProtocols.None, true);

After the call to AuthenticateAsClient, stream.IsMutuallyAuthenticated is false on Windows but true on Linux.

Configuration

This affects Linux but not Windows (I'm not sure about Mac).

Platform details:

  • .NET Core 3.1.302
  • OpenSSL 1.1.1d
  • Debian 10

Other information

A Wireshark dump verifies that the server doesn't request a client certificate. I can provide the dump file if needed, but I won't make it public because of MAC addresses.

This is not a security vulnerability because it does not affect the authentication of the client to the server or the server to the client. It only makes the client think that it has authenticated itself to the server.

Activity

  1. wfurt commented on Aug 4, 2020

    @wfurt
    Member

    It seems like the code looks for availability of certificate for both sides. As you mentioned, that does not proof that sever actually asked for it. I don't know if OpenSSL has API to track that.

  2. added
    help wanted[up-for-grabs] Good issue for external contributors
    and removed
    untriagedNew issue has not been triaged by the area owner
    on Aug 4, 2020
  3. added this to the Future milestone on Aug 4, 2020
  4. Serg046 commented on Aug 22, 2020

    @Serg046
    Contributor

    The flag is false on Windows because of the following line
    https://github.com/dotnet/runtime/blob/master/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs#L592
    _context.LocalClientCertificate is null if that clientCertificate is null.
    Seems the line is not executed on Linux.

  5. self-assigned this
    on Jan 6, 2022
  6. rzikm commented on Jan 10, 2022

    @rzikm
    Member

    The _context.LocalClientCertificate happens to be null on Windows because SslStreamPal.StartMutualAuthAsAnonymous is true on Windows, and the client certificate gets nulled at https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs#L584 the first time AcquireClientCredentials is called. If server requests the client certificate, then AcquireClientCredentials is called again and full credentials are provided.

    On Linux (and OSx as well), the StartMutualAuthAsAnonymous is false, so the LocalClientCertificate property gets always populated if client certificate was provided by the user. However, OpenSSL does not provide an easy way to check if the client certificate was actually requested by the server. The only way we could find out is to rewrite the code to always use cert callbacks (either using SSL_set_cert_cb or SSL_CTX_set_client_cert_cb) and note down if the callback was called during the handshake process.

    #63200 already adds usage of SSL_set_cert_cb to support (.NET-side) certificate selection callback, so I suggest to revisit this issue once that PR is merged and try building on those changes.

  7. assigned and unassigned on Jan 10, 2022
  8. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Jan 18, 2022
  9. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Jan 26, 2022
  10. removed their assignment
    on Feb 14, 2022
  11. ghost locked as resolved and limited conversation to collaborators on Mar 16, 2022
  12. modified the milestones: Future, 7.0.0 on Apr 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions