Runtime: Cannot find `libSystem.Security.Cryptography.Native.OpenSsl` assembly when using Roslyn in Blazor WASM

Created on 22 Jul 2020  路  21Comments  路  Source: dotnet/runtime

Describe the bug

I am using Roslyn (e.g. Microsoft.CodeAnalysis.CSharp.*) in a Blazor WASM project. My code was working fine in 3.2, but after upgrading to 5.0-Preview7, I now receive the following runtime error when calling SemanticModel.GetDiagnostics().

blazor.webassembly.js:1 Uncaught (in promise) Error: System.TypeInitializationException: The type initializer for 'Crypto' threw an exception.
 ---> System.DllNotFoundException: libSystem.Security.Cryptography.Native.OpenSsl assembly:<unknown assembly> type:<unknown type> member:(null)
   at Interop.Crypto..cctor()
   --- End of inner exception stack trace ---
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
--- End of stack trace from previous location ---
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime jsRuntime, DotNetInvocationInfo& callInfo, IDotNetObjectReference objectReference, String argsJson)
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime jsRuntime, DotNetInvocationInfo invocationInfo, String argsJson)
    at Object.endInvokeDotNetFromJS (http://localhost:51214/_framework/blazor.webassembly.js:1:3112)
    at Object.invokeJSFromDotNet (http://localhost:51214/_framework/blazor.webassembly.js:1:2732)
    at _mono_wasm_invoke_js_marshalled (http://localhost:51214/_framework/dotnet.5.0.0-preview.7.20364.11.js:1:164798)
    at do_icall (<anonymous>:wasm-function[5230]:0xe660d)
    at do_icall_wrapper (<anonymous>:wasm-function[1665]:0x4787d)
    at interp_exec_method (<anonymous>:wasm-function[1200]:0x29604)
    at interp_runtime_invoke (<anonymous>:wasm-function[4814]:0xcc5f0)
    at mono_jit_runtime_invoke (<anonymous>:wasm-function[4317]:0xb63e1)
    at do_runtime_invoke (<anonymous>:wasm-function[1664]:0x477c6)
    at mono_runtime_try_invoke (<anonymous>:wasm-function[422]:0xd74c)

To Reproduce

In a Blazor WASM .Net 5.0-Preview7 project, add references to latest C# Roslyn compiler assemblies, and invoke the Roslyn compiler as follows:

var compilation = CSharpCompilation.Create(...);
var model = compilation.GetSemanticModel(tree);
var diag = model.GetDiagnostics();  // <--  Exception thrown here

Code works fine in 3.2, but fails in 5.0-Preview7.

arch-wasm area-AssemblyLoader-mono

Most helpful comment

This also leads to signalr being unable to connect via websockets to a remote server in blazor wasm:

fail: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[11]
      Failed to start connection. Error starting transport 'WebSockets'.
System.Net.WebSockets.WebSocketException (0x80004005): Unable to connect to the remote server
 ---> System.TypeInitializationException: The type initializer for 'Crypto' threw an exception.
 ---> System.DllNotFoundException: libSystem.Security.Cryptography.Native.OpenSsl assembly:<unknown assembly> type:<unknown type> member:(null)
   at Interop.Crypto..cctor()
   --- End of inner exception stack trace ---
   at Internal.Cryptography.HashProviderDispenser.CreateHashProvider(String hashAlgorithmId)
   at System.Security.Cryptography.SHA1.Implementation..ctor()
   at System.Security.Cryptography.SHA1.Create()
   at System.Net.WebSockets.WebSocketHandle.CreateSecKeyAndSecWebSocketAccept()
   at System.Net.WebSockets.WebSocketHandle.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.WebSocketHandle.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.StartAsync(Uri url, TransferFormat transferFormat, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartTransport(Uri connectUrl, HttpTransportType transportType, TransferFormat transferFormat, CancellationToken cancellationToken)

All 21 comments

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq
Notify danmosemsft if you want to be subscribed.

/cc @marek-safar

Tagging subscribers to this area: @CoffeeFlux
See info in area-owners.md if you want to be subscribed.

Seems like a loader or build problem? The runtime can't find OpenSSL. cc: @lewing @kg

Tagging subscribers to this area: @CoffeeFlux
See info in area-owners.md if you want to be subscribed.

Yeah this is going to be an issue. That error should be different in recent builds but the code will still fail because the Cryptography classes are no longer available.

I'm curious how this might be addressed? My understanding is that you can't FFI in to system libraries from wasm, and .NET doesn't ship crypto libraries. What is the plan / roadmap for cryptographic primitives in wasm?

What changed in preview 7 that this is now coming up?

@vcsjones in preview 7 Blazor switched from the mono-based BCL (which had managed implementations for most of the crypto primitives) to the one from dotnet/runtime which relies on OpenSSL and that had to be disabled.

Would like to mention this also started appearing in the generation of PDF files using iTextSharp which worked fine in 3.2 but not any more in 5.0 due to System.DllNotFoundException: libSystem.Security.Cryptography.Native.OpenSsl assembly:<unknown assembly> type:<unknown type> member:(null)

@lewing @akoeplinger What API does Roslyn call?

@marek-safar Looks like Roslyn uses the SHA/MD5 algorithms to digest source files. https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/Portable/CryptographicHashProvider.cs

I'm closing this as the original issue was fixed in Preview 8. We are now tracking the .NET5 crypto regressions in #40076.

This also leads to signalr being unable to connect via websockets to a remote server in blazor wasm:

fail: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[11]
      Failed to start connection. Error starting transport 'WebSockets'.
System.Net.WebSockets.WebSocketException (0x80004005): Unable to connect to the remote server
 ---> System.TypeInitializationException: The type initializer for 'Crypto' threw an exception.
 ---> System.DllNotFoundException: libSystem.Security.Cryptography.Native.OpenSsl assembly:<unknown assembly> type:<unknown type> member:(null)
   at Interop.Crypto..cctor()
   --- End of inner exception stack trace ---
   at Internal.Cryptography.HashProviderDispenser.CreateHashProvider(String hashAlgorithmId)
   at System.Security.Cryptography.SHA1.Implementation..ctor()
   at System.Security.Cryptography.SHA1.Create()
   at System.Net.WebSockets.WebSocketHandle.CreateSecKeyAndSecWebSocketAccept()
   at System.Net.WebSockets.WebSocketHandle.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.WebSocketHandle.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.StartAsync(Uri url, TransferFormat transferFormat, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartTransport(Uri connectUrl, HttpTransportType transportType, TransferFormat transferFormat, CancellationToken cancellationToken)

@msschl what version of .NET are you seeing that stack trace from, it should be failing in a different place.

@lewing
blazor-wasm, net5.0

$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   5.0.100-preview.7.20366.6
 Commit:    0684df3a5b

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18362
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\5.0.100-preview.7.20366.6\

Host (useful for support):
  Version: 5.0.0-preview.7.20364.11
  Commit:  53976d38b1

Microsoft.AspNetCore.SignalR.Client Version: 5.0.0-preview.7.*

you shouldn't see this failure in preview 8

Ok, I'll retest as soon as preview 8 is released.

To be clear, in preview8 you'll still get an exception but it will be a proper PlatformNotSupportedException rather than some misleading error about not finding libSystem.Security.Cryptography.Native.OpenSsl.

We're looking at adding support for the hash functions as part of https://github.com/dotnet/runtime/issues/40076

@akoeplinger preview 8 has browser websockets so it should hopefully just work.

@lewing ah I see, I was only looking at the part of the stacktrace that hit System.Security.Cryptography.SHA1.Create() 馃槃

@lewing In preview 8 it's actually worse. Before, the above mentioned exception got thrown, then signalr switched to long-polling and the site kept working. In preview 8 another exception (see issue #25259) gets thrown and the site stops working completely.

Was this page helpful?
0 / 5 - 0 ratings