Skip to content

NotSupportedException at at System.Security.Cryptography.HMAC.HashFinal() #59289

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

Closed
mmacagno opened this issue Sep 17, 2021 · 7 comments
Closed
Labels
area-System.Security tracking-external-issue The issue is caused by external problem (e.g. OS) - nothing we can do to fix it directly
Milestone

Comments

@mmacagno
Copy link

mmacagno commented Sep 17, 2021

Description

Related to: sshnet/SSH.NET#776

I am using SSH.NET to connect to a SFTP Client with private key.
I can succesfully connect to the website using an interactive client (FileZilla)
When using the SSH.NET library, the exception I get is internal to .NET:

Exception:
Accessing a hash algorithm by manipulating the HashName property is not supported on this platform. Instead, you must instantiate one of the supplied subtypes (such as HMACSHA1.)

Other users have reported same issue with password authentication.
They also claim that the problem does not occur if they use the same SSH.NET library from .NET Framework.

I don't know any workarounds.
Is this a known issue? Fixed maybe in .NET5?

Configuration

DOTNETCORE 3.1
Windows 10 x64
Using SSH.NET

Other information

Full stack trace:

" at System.Security.Cryptography.HMAC.HashFinal() in //src/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/HMAC.cs:line 68\r\n at Renci.SshNet.Security.Cryptography.HMACSHA1.HashFinal()\r\n at System.Security.Cryptography.HashAlgorithm.CaptureHashCodeAndReinitialize() in //src/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/HashAlgorithm.cs:line 115\r\n at Renci.SshNet.Session.SendMessage(Message message)\r\n at Renci.SshNet.Session.Connect()\r\n at Renci.SshNet.BaseClient.CreateAndConnectSession()\r\n at Renci.SshNet.BaseClient.Connect()\r\n at ... (my code)

Exception type:
{Name = "PlatformNotSupportedException" FullName = "System.PlatformNotSupportedException"} Assembly: {System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e} AssemblyQualifiedName: "System.PlatformNotSupportedException, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" Attributes: Public | Serializable | BeforeFieldInit BaseType: {Name = "NotSupportedException" FullName = "System.NotSupportedException"} Cache: {System.RuntimeType.RuntimeTypeCache} CacheIfExists: {System.RuntimeType.RuntimeTypeCache} ContainsGenericParameters: false CustomAttributes: Count = 4 DeclaredConstructors: {System.Reflection.ConstructorInfo[4]} DeclaredEvents: {System.Reflection.EventInfo[0]} DeclaredFields: {System.Reflection.FieldInfo[0]} DeclaredMembers: {System.Reflection.MemberInfo[4]} DeclaredMethods: {System.Reflection.MethodInfo[0]} DeclaredNestedTypes: {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22} DeclaredProperties: {System.Reflection.PropertyInfo[0]} DeclaringMethod: '((System.RuntimeType)exception.GetType()).DeclaringMethod' threw an exception of type 'System.InvalidOperationException' }

@ghost ghost added area-System.Security untriaged New issue has not been triaged by the area owner labels Sep 17, 2021
@ghost
Copy link

ghost commented Sep 17, 2021

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Related to: sshnet/SSH.NET#776

I am using SSH.NET to connect to a SFTP Client with private key.
I can succesfully connect to the website using an interactive client (FileZilla)
When using the SSH.NET library, the exception I get is internal to .NET:

Exception:
Accessing a hash algorithm by manipulating the HashName property is not supported on this platform. Instead, you must instantiate one of the supplied subtypes (such as HMACSHA1.)

Other users have reported same issue with password authetication.
They also claim that the problem does not occur if they use the same SSH.NET library from .NET Framework.

I don't know any workarounds.
Is this a known issue? Fixed maybe in .NET5?

Configuration

DOTNETCORE 3.1
Windows 10 x64
Using SSH.NET

Other information

Full stack trace:

" at System.Security.Cryptography.HMAC.HashFinal() in //src/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/HMAC.cs:line 68\r\n at Renci.SshNet.Security.Cryptography.HMACSHA1.HashFinal()\r\n at System.Security.Cryptography.HashAlgorithm.CaptureHashCodeAndReinitialize() in //src/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/HashAlgorithm.cs:line 115\r\n at Renci.SshNet.Session.SendMessage(Message message)\r\n at Renci.SshNet.Session.Connect()\r\n at Renci.SshNet.BaseClient.CreateAndConnectSession()\r\n at Renci.SshNet.BaseClient.Connect()\r\n at ... (my code)

Exception type:
{Name = "PlatformNotSupportedException" FullName = "System.PlatformNotSupportedException"} Assembly: {System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e} AssemblyQualifiedName: "System.PlatformNotSupportedException, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" Attributes: Public | Serializable | BeforeFieldInit BaseType: {Name = "NotSupportedException" FullName = "System.NotSupportedException"} Cache: {System.RuntimeType.RuntimeTypeCache} CacheIfExists: {System.RuntimeType.RuntimeTypeCache} ContainsGenericParameters: false CustomAttributes: Count = 4 DeclaredConstructors: {System.Reflection.ConstructorInfo[4]} DeclaredEvents: {System.Reflection.EventInfo[0]} DeclaredFields: {System.Reflection.FieldInfo[0]} DeclaredMembers: {System.Reflection.MemberInfo[4]} DeclaredMethods: {System.Reflection.MethodInfo[0]} DeclaredNestedTypes: {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22} DeclaredProperties: {System.Reflection.PropertyInfo[0]} DeclaringMethod: '((System.RuntimeType)exception.GetType()).DeclaringMethod' threw an exception of type 'System.InvalidOperationException' }

Author: mmacagno
Assignees: -
Labels:

area-System.Security, untriaged

Milestone: -

@GrabYourPitchforks
Copy link
Member

The SSH.NET project has a custom type which subclasses HMACSHA1 and whose HashFinal method calls base.HashFinal.

https://github.com/sshnet/SSH.NET/blob/583a9cea6a2cacdc63bb353ed2f5867613f24271/src/Renci.SshNet/Security/Cryptography/HMACSHA1.cs#L53-L57

If this library is compiled against .NET Framework, where the HMACSHA1 type never defined an override of HMAC.HashFinal, then I'm guessing the compiler would emit a non-virtual call statement to the base method HMAC.HashFinal. Once this library is run on .NET Core / .NET 5+, that non-virtual call statement remains, and the dispatch once again gets funneled to the base method instead of the newly introduced intermediary HMACSHA1.HashFinal.

Seems like our introduction of a method override in an unsealed type has introduced a behavioral breaking change between .NET Framework and .NET Core / .NET 5.

@ericstj @bartonjs As people who understand binary compat better than me, does this theory seem sound?

@mmacagno
Copy link
Author

Thanks @GrabYourPitchforks for the comment. If that is the case, a workaround would be to clone SSH.NET and recompile it against .NET Core?

@mmacagno
Copy link
Author

mmacagno commented Sep 20, 2021

Note: our business partner reports that this works with .NET Core 2.1.
So to summarize:
.NET Framework (undisclosed version): works
.NET Core 2.1: works
.NET Core 3.1: does not work
.NET 5: not tested

@vcsjones
Copy link
Member

.NET Core 2.1: works
.NET Core 3.1: does not work

This is interesting since HMACSHA1 has zero changes to it between 2.1 and 3.1 and their override / "virtualness" doesn't seem to have changed.

Both have an override for HashFinal.

@bartonjs
Copy link
Member

I think the problem would just fix itself if https://github.com/sshnet/SSH.NET/blob/a5bd08d655bb6a3c762306472cec354556dca3a3/src/Renci.SshNet/Renci.SshNet.csproj#L10 added a target for .NET (netcoreapp3.1, net5.0, whatever), and it stems from the netstandard2.0 definition of HMACSHA1:

https://github.com/dotnet/standard/blob/52777e1506d39f64d12550e0703c4bd5e7e9f218/netstandard/ref/mscorlib.cs#L12236-L12241:

    public partial class HMACSHA1 : System.Security.Cryptography.HMAC
    {
        public HMACSHA1() { }
        public HMACSHA1(byte[] key) { }
        public HMACSHA1(byte[] key, bool useManagedSha1) { }
    }

which matches the .NET Framework implementation of the type: https://referencesource.microsoft.com/#mscorlib/system/security/cryptography/hmacsha1.cs,ac2ad0c1e5c1be3e.

This is one of those frustrating things where doing more work in the compiler (determining the specific derived type that base.Foo will target) produces wrong answers (the runtime handles missing overrides or methods "moving down", just costs an extra few CPU cycles at JIT time).

@bartonjs bartonjs added tracking-external-issue The issue is caused by external problem (e.g. OS) - nothing we can do to fix it directly and removed untriaged New issue has not been triaged by the area owner labels Oct 1, 2021
@bartonjs bartonjs added this to the Future milestone Oct 1, 2021
@mmacagno
Copy link
Author

mmacagno commented Oct 25, 2021

@bartonjs I just wanted to follow up on this: I forked the (SSH.NET) repository and made the explicit build for .NET Core 3.1 and .NET 5.0 and the issue was resolved / worked around.
Thanks for your help.
mac

@ghost ghost locked as resolved and limited conversation to collaborators Nov 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Security tracking-external-issue The issue is caused by external problem (e.g. OS) - nothing we can do to fix it directly
Projects
None yet
Development

No branches or pull requests

4 participants