Repository navigation
build(ffi): move to the upstream diplomat .NET backend - #518
Closed
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit into
Closed
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit into
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit into
Conversation
Swaps the old CBenoit diplomat fork for the rewritten .NET backend, pinned to the blittable-bool fix (rust-diplomat/diplomat#1226) so Result and Option still marshal on .NET Framework. Rust side: DiplomatWriteable is now DiplomatWrite, the bridge macro derives Clone/Copy on enums itself, mutable opaques need opaque_mut, Result errors have to be diplomat types (Pkcs12Error -> Box<PickyError>), and box-in-input is gone (Option<Box<RsString>> -> Option<&RsString>). The generated C# API changes shape: setters are methods (Kid = x becomes SetKid(x)) and enum variants are re-cased (RS512 -> Rs512). Devolutions.Picky itself builds clean; Devolutions.Picky.Tests still needs porting to the new names. Adds Devolutions.Picky.Net48Tests, which runs the bindings on .NET Framework 4.8 and on modern .NET so the marshalling stays proven on both.
irvingouj@Devolutions (irvingoujAtDevolution)
added a commit
that referenced
this pull request
Oct 17, 2026
Moves the .NET bindings off the old [CBenoit/diplomat@f4d93d57](CBenoit/diplomat@f4d93d5) fork onto Diplomat's HIR .NET backend, pinned to the protected tag [`0.16.1-devo.2`](https://github.com/Devolutions/diplomat/tree/0.16.1-devo.2) (same commit as upstream main, [002db80c](rust-diplomat/diplomat@002db80)). crates.io 0.16.1 predates the .NET lifetime rework, so it's a tag until upstream publishes. Supersedes #518. Split into a stack so this one is just the migration: 1. #561 drops .NET Framework, targets net8.0 2. #537 `program_name` double free fix 3. #538 getter/setter attrs, no generated diff 4. #569 `manually_disposable` on the 14 types that need it, no generated diff 5. this PR 6. #541 fixes a use-after-free in `AuthenticodeValidator` 7. #542 wipes key bytes and passphrases on free The bridge diff here is only what HIR needs: `opaque_mut`, named lifetimes, `DiplomatWrite`, and no `#[derive(Clone, Copy)]` on enums (the macro adds it now). The rest is `Generated/`, the addons and test renames. C# properties stay the same (176 before, 176 after). ### Breaking (C#) - `GetX()`/`SetX()` methods that duplicated properties are gone; the properties stay - `HashAlgorithm`/`ShaVariant`/`JwsAlg`/`SshCertKeyType` members are re-cased (`SHA2_256` → `Sha2256`), same numeric values - `DiplomatWriteable`, `AsFFI()`, the raw ctors and `Raw.*` aren't public anymore; `PickyError.ToDisplay()` returns `string` - only the 14 types from #569 stay `IDisposable`, the other 84 lose it, so `using`/`Dispose()` on them won't compile anymore I grepped the RDM monorepo (RDM, DVLS, Hub, PowerShell): none of the removed methods or enum names are used. They do dispose `Cert` and `using` `Pkcs12ParsingParams`/`Pkcs12Attribute`, those lines have to go when they bump. That's a text search, not a compile. ### Where to look hardest - the addons take a shared lease for the whole native call, same as the generated code: [Pem](https://github.com/Devolutions/picky-rs/blob/d44f8bf021013f285fbd360defe1fb1f964d64b4/ffi/dotnet/Devolutions.Picky/src/Pem.Addons.cs), [Pfx](https://github.com/Devolutions/picky-rs/blob/d44f8bf021013f285fbd360defe1fb1f964d64b4/ffi/dotnet/Devolutions.Picky/src/Pfx.Addons.cs), [PublicKey](https://github.com/Devolutions/picky-rs/blob/d44f8bf021013f285fbd360defe1fb1f964d64b4/ffi/dotnet/Devolutions.Picky/src/PublicKey.Addons.cs) - the test renames in `JwtTests`/`Pkcs7Tests`/`SshTests`, that's what consumers will have to change ### Tests - clippy/fmt clean, regenerating the bindings is a no-op (267/267 files) - `Devolutions.Picky.Tests` 26/26 ### Needs a call - NuGet is date-versioned with no changelog. How do we want to announce the breaks? ### Not from this PR, spotted while here - `PuttyPpkEncryptionConfigBuilder` setters call `self.0.clone().x(..)` and throw the result away, so they do nothing - `get_argon2_flavour` is a setter with a getter name Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft — the diplomat side isn't merged yet.
Gets us off the old CBenoit diplomat fork and onto the rewritten .NET backend. Pinned to my rust-diplomat/diplomat#1226 (fixed-width bool tag) because without it every
Result/Optionreturn throwsMarshalDirectiveExceptionon .NET Framework —boolisn't blittable, so P/Invoke can't return the struct by value. Once that lands upstream I'll repoint the rev at rust-diplomat and drop the fork.Rust side had to move with the new backend:
DiplomatWriteable→DiplomatWrite, the bridge macro derivesClone/Copyon enums now, mutable opaques needopaque_mut,Resulterrors must be diplomat types (Pkcs12Error→Box<PickyError>), and box-in-input is gone.builder.Kid = x→builder.SetKid(x)) and enum variants got re-cased (RS512→Rs512,SHA2_256→Sha2256).Still to do:
Devolutions.Picky.Testsdoesn't compile against the new names (56 errors, all mechanical renames). Didn't want to bury it in this diff — happy to do it here or as a follow-up, tell me which.Tests: new
Devolutions.Picky.Net48Testsruns the bindings on net48 and net10, 14/14 on both. Covers every marshalling shape — object/void/primitive/string/option Results, bool in and out,byte[]returns, iterators, error → exception.