jedisct1 / libsodium

A modern, portable, easy to use crypto library.
https://libsodium.org
Other
12.06k stars 1.72k forks source link

Support for `netX-maccatalyst` TFM in .NET #1369

Closed MartyIX closed 2 months ago

MartyIX commented 2 months ago

This PR adds support for using libsodium in Mac Catalyst .NET projects.

Testing

I was testing this PR on my next branch (https://github.com/MartyIX/libsodium/actions/runs/8745576446) and it created: nuget-package

The nuget package can be tested with my demo application on Mac Catalyst:

https://github.com/MartyIX/MaccatalystLibsodium

The only modified file in the "empty Mac Catalyst" project is this file: https://github.com/MartyIX/MaccatalystLibsodium/blob/main/MaccatalystLibsodium/AppDelegate.cs where I added some calls into libsodium library.

Screenshot

image

Resources

MartyIX commented 2 months ago

The nuget package contents look like this:

image

MartyIX commented 2 months ago

cc @ektrah if you are interested. There is https://github.com/ektrah/libsodium-core/issues/80 issue on your end which is not fixed by this PR I think. I don't know anything about the state of iOS support.

ektrah commented 2 months ago

@jedisct1 BTW, it's possible to make prereleases of NuGet packages by setting the <Version> property in libsodium.pkgproj like this:

-<Version>1.0.21.0</Version>
+<Version>1.0.21.0-preview.1</Version>
jedisct1 commented 2 months ago

A new package (1.0.19.1) is now available on NuGet, and includes Catalyst. Let me know if it works!

ektrah commented 2 months ago

Version 1.0.19.1 is broken on Alpine Linux because the NuGet package does not contain a runtimes/linux-musl-x64/native/libsodium.so.

Package contents: https://nuget.info/packages/libsodium/1.0.19.1

Failing test: https://github.com/ektrah/nsec/actions/runs/8869195585/job/24349607561

jedisct1 commented 2 months ago

runtimes/linux-musl-x64/native/libsodium.a should be there.

Is a shared library required even for musl?

alexrp commented 2 months ago

linux-musl in .NET refers to systems that use musl as a system-wide shared library, e.g. Alpine.

jedisct1 commented 2 months ago

I don't get how it used to work before, if it did. Zig can only create static libraries when using musl.

ektrah commented 2 months ago

Assuming this is the right commit, it looks like the runtimes/linux-musl-x64/native/libsodium.so in the 1.0.19 NuGet package was built in an Alpine 3.13 container: https://github.com/jedisct1/libsodium/blob/b5bd5b877116948b7d68bfd3f308bdc2953cca6c/.github/workflows/dotnet-core.yml#L101-L124

It's a bit difficult to tell which exact commit was used back at the time, though. A few commits earlier, the binary was still built using make: https://github.com/jedisct1/libsodium/blob/a7c4cd8b83ad2c5a58ec2749aa8faaf417feee6e/.github/workflows/dotnet-core.yml#L113-L136

alexrp commented 2 months ago

The .NET SDK will currently only use static libraries under runtimes/... for certain Apple platforms (iOS and friends). Shipping a static library for a Linux-based platform under runtimes/... has no effect.

It actually seems like https://github.com/ziglang/zig/issues/11909 does not affect libraries:

❯ zig cc test.c -target x86_64-linux-musl -shared -fPIC -o libtest.so^C
❯ bat test.c
       File: test.c
   1   #include <stdio.h>
   2   
   3   void hello_world()
   4   {
   5       printf("hello world\n");
   6   }
❯ zig cc test.c -target x86_64-linux-musl -shared -fPIC -o libtest.so
❯ file libtest.so
libtest.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped
❯ readelf -d libtest.so

Dynamic section at offset 0x3c0 contains 16 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x000000000000001e (FLAGS)              BIND_NOW
 0x000000006ffffffb (FLAGS_1)            Flags: NOW
 0x0000000000000017 (JMPREL)             0x2f8
 0x0000000000000002 (PLTRELSZ)           24 (bytes)
 0x0000000000000003 (PLTGOT)             0x24c0
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000006 (SYMTAB)             0x200
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000005 (STRTAB)             0x2d0
 0x000000000000000a (STRSZ)              40 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x278
 0x0000000000000004 (HASH)               0x2a0
 0x000000000000000c (INIT)               0x1394
 0x000000000000000d (FINI)               0x1397
 0x0000000000000000 (NULL)               0x0

(And so on for other architectures.)

The issue is, however, still there for executables.

So I would suggest just going back to shipping shared objects for musl as before.

jedisct1 commented 2 months ago

Ok, I think e77588fe8fae5d9948a9534aa39f32e1ba076407 is the key.

ektrah commented 2 months ago

BTW, CentOS Linux 7 will reach end of life (EOL) on June 30, 2024.

.NET 8 has already dropped support for it; see https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md

.NET 7 and .NET 6 will reach end of life on May 14, 2024 and November 12, 2024, respectively.
https://github.com/dotnet/core/blob/main/release-notes/7.0/supported-os.md
https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md

actions/upload-artifact@v3 is scheduled for deprecation on November 30, 2024.

From my point of view I think it's okay to drop support for those ancient Linux versions in the libsodium NuGet package already now and go forward with the platforms supported by .NET 8.

jedisct1 commented 2 months ago

Oh, this is good news!

MartyIX commented 2 months ago

My Mac Catalyst app https://github.com/MartyIX/MaccatalystLibsodium (https://github.com/MartyIX/MaccatalystLibsodium/commit/54f9c723b8cab21fc92cf1bdbe8923842a0dde71) works with the latest released libsodium (https://www.nuget.org/packages/libsodium/1.0.19.2).

Thank you.

MartyIX commented 2 months ago

@ektrah Could you please upgrade your https://github.com/ektrah/libsodium-core to be based on 1.0.19.2?

ektrah commented 2 months ago

Will do. I think that's not the only change needed for iOS/tvOS/MacCatalyst support though, is it?

Try this: Add both NuGet packages to your project, i.e. both libsodium-core 1.3.5 and libsodium 1.0.19.2. This should cause libsodium-core 1.3.5 to use libsodium 1.0.19.2 instead of 1.0.19. I don't think this will fully work yet, though, as the __Internal magic is still missing in libsodium-core 1.3.5.

MartyIX commented 2 months ago

Will do. I think that's not the only change needed for iOS/tvOS/MacCatalyst support though, is it?

I'm not sure but this was enough for me: https://github.com/MartyIX/MaccatalystLibsodium/blob/54f9c723b8cab21fc92cf1bdbe8923842a0dde71/MaccatalystLibsodium/AppDelegate.cs#L13-L32

Try this: Add both NuGet packages to your project, i.e. both libsodium-core 1.3.5 and libsodium 1.0.19.2. This should cause libsodium-core 1.3.5 to use libsodium 1.0.19.2 instead of 1.0.19. I don't think this will fully work yet, though, as the __Internal magic is still missing in libsodium-core 1.3.5.

I'll try it when I have a chance (I don't have my macOS machine with me right now) but perhaps you could just release a preview version for people to test it.

ektrah commented 2 months ago

Done. v1.4.0-preview.1

Please try it and provide feedback here.