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

Request for updated Nuget Release #73

Closed
enclave-alistair opened this issue May 9, 2023 · 9 comments
Closed

Request for updated Nuget Release #73

enclave-alistair opened this issue May 9, 2023 · 9 comments

Comments

@enclave-alistair
Copy link

Hi @ektrah, can I inquire as to your plans for the next nuget package release? We're currently maintaining a forked build so we can get your commit for "unmanaged function pointers" (114231a), needed for iOS support, as a package.

I know iOS isn't on your official supported list, but we're using NSec quite successfully with a few build/loader tweaks in the iOS app, would be nice to switch over to the regular NSec package.

@ektrah
Copy link
Owner

ektrah commented May 14, 2023

I didn't think the changes since the last release were significant enough for a new release, but I've done a new pre-release now. If all looks good, I could do a new release soon.

Having iOS on the official support list would be nice. However, I still haven't been able to fully figure out what is needed for this. Are the changes in 114231a enough or is there anything else that should be done in NSec (or libsodium) to help making it work?

@enclave-alistair
Copy link
Author

So, as you may be aware, iOS is a bit of a pain. To make libsodium correctly load and be consumed by NSec, here's what you need in the iOS project.

1. Libsodium build for iOS

You need a built libsodium.a for iOS. This could be avoided if the libsodium nuget shipped an iOS build, which would be just about doable I think with a GitHub macOS build runner.

2. Include the binary in your bundle

Add:

<NativeReference Include="Platforms/iOS/libsodium.a" Kind="Static" ForceLoad="True" />

in the project file (probably in an '$(TargetFramework)'=='net7.0-ios') conditional.

3. Tell the runtime where the libsodium symbols are

The iOS build will statically link all the libsodium symbols directly into the generated binary, but that means there is no longer in a "libsodium" library to DllImport, so we must tell it, using NativeLibrary.SetDllImportResolver():

// As early in your app as possible.
NativeLibrary.SetDllImportResolver(typeof(NSec.Cryptography.Ed25519).Assembly, ResolveLibsodium);

private static IntPtr ResolveLibsodium(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
    if (libraryName == "libsodium")
    {
        return NativeLibrary.GetMainProgramHandle();
    }

    // fall back to the system resolver.
    return IntPtr.Zero;
}

This is not necessary if the NSec library uses __Internal rather than libsodium for its DllImport attributes (__Internal is a special value that the runtime understands as "this program"), but obviously that only works on iOS.

4. Preserve the libsodium symbols from being trimmed out

Due to point 3, there is now no compile-time connection between the libsodium symbols consumed by the NSec library and the symbols themselves. So, the iOS compiler strips them out, removing all those libsodium functions.

To get around that, we currently duplicate the Interop folder into our app, and change the Interop.Libraries.Libsodium constant to __Internal. These Interop functions are not used, but "trick" the compiler into preserving the symbols.

My instinct tells me that there may be a way to communicate this list of "preserve these symbols please" to the iOS compiler, but I haven't found a better way yet other than duplicating the code as we currently do.

It may be that if the NSec library did similar and included __Internal variants of all it's interop methods that those would propagate and preserve the symbols, but I'm not sure, and that's really janky.

@ektrah
Copy link
Owner

ektrah commented May 15, 2023

I've created a branch that changes the Interop.Libraries.Libsodium constant to __Internal on iOS: master...ios. Here is the NuGet package: artifact.zip. Could you check if that helps with 3. and 4.?

Could MSBuild .props and .targets in a package help making 2. more convenient?

Regarding 1., libsodium builds pre-compiled binaries for all Apple targets, but seems not to have included them in the NuGet package yet.

@enclave-alistair
Copy link
Author

Don't props and targets in a package only apply to the directly-referencing package? What happens if it's referenced indirectly (as we do)?

If libsodium could build iOS and Android binaries into its nuget package, that would be superb, because we then don't need to maintain their own. I hadn't seen there were apple-target binaries available.

@ektrah
Copy link
Owner

ektrah commented May 15, 2023

The linked page talks about buildTransitive (NuGet 5.0+) for assets that flow transitively. I've never tried that yet though.

There has been some great discussion in jedisct1/libsodium#1235 about MacCatalyst support that also helps with iOS support (PR: jedisct1/libsodium#1238). I think there are still a few last pieces missing, but not much. I don't know about Android.

@ektrah
Copy link
Owner

ektrah commented Jun 10, 2023

@enclave-alistair Any feedback on the ios branch?

@davhdavh
Copy link

libsodium 1.0.19 was released, and the current NSec.Cryptography is locked to < 1.0.19

@samuel-lucas6
Copy link

@davhdavh There's a preview release that supports 1.0.19. Even if there wasn't, it's important to remember that 1.0.19 was only released recently and people are busy and work on other things.

@ektrah
Copy link
Owner

ektrah commented Apr 27, 2024

An updated NuGet package including the commit for "unmanaged function pointers" has been released.

@ektrah ektrah closed this as completed Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants