Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion .github/workflows/main-push-nuget-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
push:
branches: [ "main" ]

permissions:
contents: read

jobs:
native-windows:
runs-on: windows-latest
Expand Down Expand Up @@ -54,9 +57,55 @@ jobs:
name: native-linux
path: cas-dotnet-sdk/artifacts/native/linux-x64

native-macos-arm64:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: dtolnay/rust-toolchain@stable

- name: Build Rust (macOS arm64)
working-directory: cas-core-lib
run: cargo build --release

- name: Stage native
run: |
mkdir -p cas-dotnet-sdk/artifacts/native/osx-arm64
cp cas-core-lib/target/release/libcas_core_lib.dylib cas-dotnet-sdk/artifacts/native/osx-arm64/

- uses: actions/upload-artifact@v4
with:
name: native-osx-arm64
path: cas-dotnet-sdk/artifacts/native/osx-arm64

native-macos-x64:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
runs-on: macos-13
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: dtolnay/rust-toolchain@stable

- name: Build Rust (macOS x64)
working-directory: cas-core-lib
run: cargo build --release

- name: Stage native
run: |
mkdir -p cas-dotnet-sdk/artifacts/native/osx-x64
cp cas-core-lib/target/release/libcas_core_lib.dylib cas-dotnet-sdk/artifacts/native/osx-x64/

- uses: actions/upload-artifact@v4
with:
name: native-osx-x64
path: cas-dotnet-sdk/artifacts/native/osx-x64

pack-and-publish:
runs-on: ubuntu-latest
needs: [native-windows, native-linux]
needs: [native-windows, native-linux, native-macos-arm64, native-macos-x64]

steps:
- uses: actions/checkout@v4
Expand All @@ -71,11 +120,23 @@ jobs:
name: native-linux
path: cas-dotnet-sdk/artifacts/native/linux-x64

- uses: actions/download-artifact@v4
with:
name: native-osx-arm64
path: cas-dotnet-sdk/artifacts/native/osx-arm64

- uses: actions/download-artifact@v4
with:
name: native-osx-x64
path: cas-dotnet-sdk/artifacts/native/osx-x64

- name: Verify staged natives
run: |
ls -R cas-dotnet-sdk/artifacts/native
test -f cas-dotnet-sdk/artifacts/native/linux-x64/libcas_core_lib.so
test -f cas-dotnet-sdk/artifacts/native/win-x64/cas_core_lib.dll
test -f cas-dotnet-sdk/artifacts/native/osx-arm64/libcas_core_lib.dylib
test -f cas-dotnet-sdk/artifacts/native/osx-x64/libcas_core_lib.dylib

- uses: actions/setup-dotnet@v4
with:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/pr-tests-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches: [ main ]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
Expand Down
57 changes: 57 additions & 0 deletions .github/workflows/pr-tests-macos-arm64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: PR Tests - macOS arm64

on:
pull_request:
branches: [ main ]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build:
# macos-latest is Apple Silicon (osx-arm64).
runs-on: macos-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
9.0.x
10.0.x

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Build Rust native (macOS arm64)
working-directory: cas-core-lib
run: cargo build --release

- name: Stage native lib for tests
shell: bash
run: |
set -euo pipefail
for tfm in net6.0 net7.0 net8.0 net9.0 net10.0; do
OUTDIR="cas-dotnet-sdk-tests/bin/Release/${tfm}"
mkdir -p "$OUTDIR"
cp "cas-core-lib/target/release/libcas_core_lib.dylib" "$OUTDIR/"
done
ls -la cas-dotnet-sdk-tests/bin/Release

- name: Run tests (all target frameworks)
run: |
echo "Running tests for all target frameworks on macos-latest (arm64)"
dotnet test ./cas-dotnet-sdk-tests/cas-dotnet-sdk-tests.csproj -c Release --logger "trx"
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
57 changes: 57 additions & 0 deletions .github/workflows/pr-tests-macos-x64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: PR Tests - macOS x64

on:
pull_request:
branches: [ main ]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build:
# macos-13 is Intel (osx-x64).
runs-on: macos-13

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
9.0.x
10.0.x

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Build Rust native (macOS x64)
working-directory: cas-core-lib
run: cargo build --release

- name: Stage native lib for tests
shell: bash
run: |
set -euo pipefail
for tfm in net6.0 net7.0 net8.0 net9.0 net10.0; do
OUTDIR="cas-dotnet-sdk-tests/bin/Release/${tfm}"
mkdir -p "$OUTDIR"
cp "cas-core-lib/target/release/libcas_core_lib.dylib" "$OUTDIR/"
done
ls -la cas-dotnet-sdk-tests/bin/Release

- name: Run tests (all target frameworks)
run: |
echo "Running tests for all target frameworks on macos-13 (x64)"
dotnet test ./cas-dotnet-sdk-tests/cas-dotnet-sdk-tests.csproj -c Release --logger "trx"
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
3 changes: 3 additions & 0 deletions .github/workflows/pr-tests-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on:
pull_request:
branches: [ main ]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand Down
8 changes: 6 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ CAS .NET SDK is a managed cryptographic toolkit published as the [`cas-dotnet-sd

- `cas-dotnet-sdk/` — the SDK class library (NuGet package source). Multi-targets `net6.0`–`net10.0`.
- `cas-dotnet-sdk-tests/` — xUnit test project, references the SDK directly.
- `cas-core-lib/` — **git submodule** containing the Rust source compiled to `cas_core_lib.dll` (Windows) / `libcas_core_lib.so` (Linux). Clone with `--recursive` or run `git submodule update --init --recursive`.
- `cas-core-lib/` — **git submodule** containing the Rust source compiled to `cas_core_lib.dll` (Windows) / `libcas_core_lib.so` (Linux) / `libcas_core_lib.dylib` (macOS). Clone with `--recursive` or run `git submodule update --init --recursive`.
- `docs/EXAMPLES.md` — usage samples.

## Build & Test
Expand All @@ -35,6 +35,8 @@ dotnet test ./cas-dotnet-sdk-tests/cas-dotnet-sdk-tests.csproj -f net8.0 --filte
dotnet test ./cas-dotnet-sdk-tests/cas-dotnet-sdk-tests.csproj -f net8.0 --filter "DisplayName~Hash512"
```

The same commands work for local development on macOS: a Rust toolchain on PATH builds `libcas_core_lib.dylib`, and the `StageRustArtifacts` MSBuild target detects the host (Apple Silicon vs Intel) and stages it into `artifacts/native/osx-arm64/` or `artifacts/native/osx-x64/` automatically — no extra flags needed.

Note: CI (`.github/workflows/pr-tests-*.yml`) builds `cargo build --release` separately, then copies the native lib into the test `bin/Release/<tfm>` directory before running `dotnet test`. If you build the Rust lib by hand and the MSBuild target is skipped, the native artifact must end up next to the test assembly the same way.

## Architecture: the three-layer wrapper pattern
Expand Down Expand Up @@ -67,4 +69,6 @@ Categories with interchangeable algorithms expose a `*Factory` (e.g. `HasherFact

## Cross-platform constraint

Only **Windows x64** and **Linux x64** are supported (no macOS). All wrappers must keep Windows and Linux paths in sync — a function added to one platform wrapper without the other will throw `DllNotFoundException` / `EntryPointNotFoundException` on the missing platform. Tests run against .NET 6–10 on both OSes in CI on every PR.
Supported targets: **Windows x64**, **Linux x64**, and **macOS** (both `osx-arm64` Apple Silicon and `osx-x64` Intel). Since the csbindgen migration (#191), P/Invoke goes through the generated `generated/NativeMethods.g.cs` using the bare library name `cas_core_lib`; the .NET runtime resolves it per-OS to `cas_core_lib.dll` / `libcas_core_lib.so` / `libcas_core_lib.dylib`, so there are no per-platform `[DllImport]` files to keep in sync. The native lib is built (`cargo build --release`), staged into `artifacts/native/<rid>/`, and packed into `runtimes/<rid>/native` for each RID. Tests run against .NET 6–10 on all three OSes in CI on every PR: `pr-tests-windows` and `pr-tests-linux` fan out one job per TFM, while macOS is split by architecture into two separate workflows — `pr-tests-macos-arm64` (`macos-latest`, Apple Silicon) and `pr-tests-macos-x64` (`macos-13`, Intel) — each running all five target frameworks in a single `dotnet test` invocation (no `-f`). The `OperatingSystemDeterminator` resolves Windows, Linux, and OSX and throws on anything else.

Note: this is desktop **macOS / Darwin**, not iOS. Real iOS (`aarch64-apple-ios`) would need a cross-compiled native lib and a simulator/device to run tests, neither of which the current CI provides.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ CAS .NET SDK is a comprehensive cryptographic toolkit for .NET, designed to prov
- Seamless integration with [cas-lib](https://github.com/Cryptographic-API-Services/cas-lib) Rust FFI layer for optimal performance
- Unified interface: no need to manage multiple cryptography packages or surf disparate documentation
- Built on trusted, open-source cryptography libraries
- Cross-platform support: Windows x64, Linux x64
- Cross-platform support: Windows x64, Linux x64, macOS (Apple Silicon arm64 & Intel x64)
- Multi-framework support: .NET 6, 7, 8, 9, 10

## Documentation & References
Expand All @@ -26,14 +26,16 @@ We build on the work of leading cryptography projects. For in-depth algorithm de
See practical usage and code samples in our [Examples](./docs/EXAMPLES.md).

## Supported Frameworks / Operating Systems
We aim to provide cross-compatibility wherever possible. Test cases are run on .NET 6-9 for Windows and Linux (Ubuntu) on each pull request and release to NuGet through GitHub Actions.
We aim to provide cross-compatibility wherever possible. Test cases are run on .NET 6-10 for Windows, Linux (Ubuntu), and macOS on each pull request and release to NuGet through GitHub Actions.
- [X] .NET 6
- [X] .NET 7
- [X] .NET 8
- [X] .NET 9
- [X] .NET 10
- [X] Windows x64
- [X] Linux x64
- [X] macOS arm64 (Apple Silicon)
- [X] macOS x64 (Intel)

## Disclaimer
This SDK leverages several cryptographic crates via our core FFI [layer](https://github.com/Cryptographic-API-Services/cas-core-lib). Please note that many of these crates have not undergone formal security audits. Use this library at your own risk and always review the underlying cryptographic implementations for your security requirements.
Expand Down
8 changes: 5 additions & 3 deletions cas-dotnet-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ CAS .NET SDK is a comprehensive cryptographic toolkit for .NET, designed to prov
- Seamless integration with [cas-lib](https://github.com/Cryptographic-API-Services/cas-lib) Rust FFI layer for optimal performance
- Unified interface: no need to manage multiple cryptography packages or surf disparate documentation
- Built on trusted, open-source cryptography libraries
- Cross-platform support: Windows x64, Linux x64
- Multi-framework support: .NET 6, 7, 8, 9
- Cross-platform support: Windows x64, Linux x64, macOS (Apple Silicon arm64 & Intel x64)
- Multi-framework support: .NET 6, 7, 8, 9, 10

## Documentation & References
We build on the work of leading cryptography projects. For in-depth algorithm details and implementation notes, please refer to:
Expand All @@ -26,14 +26,16 @@ We build on the work of leading cryptography projects. For in-depth algorithm de
See practical usage and code samples in our [Examples](./docs/EXAMPLES.md).

## Supported Frameworks / Operating Systems
We aim to provide cross-compatibility wherever possible. Test cases are run on .NET 6-9 for Windows and Linux (Ubuntu) on each pull request and release to NuGet through GitHub Actions.
We aim to provide cross-compatibility wherever possible. Test cases are run on .NET 6-10 for Windows, Linux (Ubuntu), and macOS on each pull request and release to NuGet through GitHub Actions.
- [X] .NET 6
- [X] .NET 7
- [X] .NET 8
- [X] .NET 9
- [X] .NET 10
- [X] Windows x64
- [X] Linux x64
- [X] macOS arm64 (Apple Silicon)
- [X] macOS x64 (Intel)

## Disclaimer
This SDK leverages several cryptographic crates via our core FFI [layer](https://github.com/Cryptographic-API-Services/cas-core-lib). Please note that many of these crates have not undergone formal security audits. Use this library at your own risk and always review the underlying cryptographic implementations for your security requirements.
Expand Down
33 changes: 31 additions & 2 deletions cas-dotnet-sdk/cas-dotnet-sdk.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Title>cas-dotnet-sdk</Title>
<PackageIcon>icon.jpeg</PackageIcon>
<Version>1.9.75</Version>
<Version>1.9.76</Version>
<Authors>Mike Mulchrone</Authors>
<Description>A Nuget package that provides a implementation of the RustCrypto suite of cryptographic algorithms.</Description>
<RepositoryUrl>https://github.com/Cryptographic-API-Services/cas-dotnet-sdk</RepositoryUrl>
Expand Down Expand Up @@ -40,12 +40,25 @@
</Target>

<Target Name="StageRustArtifacts" AfterTargets="BuildRust" Condition="'$(BuildNativeRust)'=='true'">
<PropertyGroup>
<!-- $(OS) is 'Unix' on both Linux and macOS, so distinguish macOS explicitly. -->
<_IsOSX>$([MSBuild]::IsOSPlatform('OSX'))</_IsOSX>
<!-- Host arch -> RID suffix (Arm64 -> arm64, X64 -> x64) so a dev build on
Apple Silicon stages osx-arm64 and an Intel Mac stages osx-x64. -->
<_HostArch>$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant())</_HostArch>
</PropertyGroup>

<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
<_RustOut Include="$(RustProjectDir)\target\release\cas_core_lib.dll" />
<_DestDir Include="$(NativeArtifactsDir)/win-x64/" />
</ItemGroup>

<ItemGroup Condition="'$(OS)' != 'Windows_NT'">
<ItemGroup Condition="'$(_IsOSX)' == 'true'">
<_RustOut Include="$(RustProjectDir)/target/release/libcas_core_lib.dylib" />
<_DestDir Include="$(NativeArtifactsDir)/osx-$(_HostArch)/" />
</ItemGroup>

<ItemGroup Condition="'$(OS)' != 'Windows_NT' AND '$(_IsOSX)' != 'true'">
<_RustOut Include="$(RustProjectDir)/target/release/libcas_core_lib.so" />
<_DestDir Include="$(NativeArtifactsDir)/linux-x64/" />
</ItemGroup>
Expand All @@ -71,6 +84,22 @@
<Link>libcas_core_lib.so</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

<None Include="$(NativeArtifactsDir)\osx-arm64\libcas_core_lib.dylib"
Condition="Exists('$(NativeArtifactsDir)\osx-arm64\libcas_core_lib.dylib')">
<Pack>true</Pack>
<PackagePath>runtimes\osx-arm64\native</PackagePath>
<Link>libcas_core_lib.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

<None Include="$(NativeArtifactsDir)\osx-x64\libcas_core_lib.dylib"
Condition="Exists('$(NativeArtifactsDir)\osx-x64\libcas_core_lib.dylib')">
<Pack>true</Pack>
<PackagePath>runtimes\osx-x64\native</PackagePath>
<Link>libcas_core_lib.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<!--
Expand Down
Loading