Skip to content

Release 1.16.1#476

Merged
DennisDyallo merged 99 commits intomainfrom
release/1.16.1
Apr 29, 2026
Merged

Release 1.16.1#476
DennisDyallo merged 99 commits intomainfrom
release/1.16.1

Conversation

@DennisDyallo
Copy link
Copy Markdown
Collaborator

1.16.1

Release date: April 29th, 2026

Bug Fixes:

  • Fixed an issue where HID and SmartCard transport events were logged at Info level, causing excessive noise in application logs. These events have been downgraded to Debug level. (#473)

  • Fixed an issue where high idle CPU usage occurred in RDS/Terminal Server environments due to SCARD_E_INVALID_HANDLE errors in the smart card listener loop. (#445)

  • Several bugs discovered through fuzz testing have been fixed, including issues in TLV parsing and CBOR decoding. A SharpFuzz fuzzing harness and CodeQL scheduled analysis have also been added. (#458)

Documentation:

  • The documentation on EncIdentifier has been corrected with updated details and relevant links. (#456)

  • Important FIDO2 SCP support information has been added to the user's manual. (#442)

  • Inconsistencies and obsolete class references in the documentation have been addressed. (#441)

Miscellaneous:

  • The Yubico.NativeShims dependency has been switched to a floating version with packages.lock.json for safer dependency management. (#474)

  • NativeShims export sanity checks and interop known-answer tests have been added, and Hkdf tests have been relocated. (#472)

  • An SCP03 command chaining regression test has been added. (#452)

Dependencies:

  • Several dependencies across the Yubico.Core, Yubico.YubiKey, and GitHub Actions workflows have been updated to newer versions. (#449, #453, #454, #461, #462, #463, #464, #470, #471)

DennisDyallo and others added 30 commits March 30, 2026 08:40
Replace obsolete type references across 7 documentation files:
- ECPublicKeyParameters/ECPrivateKeyParameters → ECPublicKey/ECPrivateKey factory methods
- PivPublicKey/PivRsaPublicKey/PivEccPrivateKey → IPublicKey/RSAPublicKey/ECPrivateKey
- GenerateKeyPair(PivAlgorithm) → GenerateKeyPair(KeyType)
- GetDeviceInfoCommand → IYubiKeyDevice high-level API
- Fix typo Scp03KeyParamaters → Scp03KeyParameters

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- fips-mode.md: Add explicit connection establishment from device,
  fix vfyFipsMode → vfyFipsModeRsp variable name typo
- secure-channel-protocol.md: Break long line into two for readability
- attestation.md: Remove dead variable in ECC example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added note about memory security in FIDO2 PIN example.
- Specified code block language for OATH credentials example.
- Fixed syntax errors in key collector code examples.
…rotocol.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Fix non-compiling code examples (GetString→ToString, wrong variable/class
names), correct RemoveCredential→RenameCredential in rename section, and
add try/finally with CryptographicOperations.ZeroMemory to OTP examples
that handle cryptographic key material.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Updated SCP11 example to use ECParameters for public key
- Ensured clarity in code snippet for better understanding
- Fix variable name mismatch: certificateList -> certificates with semicolon
- Fix casing: scp03params -> scp03Params in PIV, OATH, OTP, YubiHSM examples
- Add missing replaceKvn argument to GenerateEcKey call
- Simplify SCP11a params: pass newPublicKey directly (already ECPublicKey)
- Replace First() with FirstOrDefault() + null guard in fips-mode examples
- Add MyKeyCollector() constructor to properly initialize CurrentValue field

Co-authored-by: Dennis Dyallo <DennisDyallo@users.noreply.github.com>
feat: update NativeShims dependency
docs: added important FIDO2 SCP support info to user's manual
…ard listener (#434)

When an RDS/Terminal Server session is disconnected, the Windows Smart Card Service
invalidates existing SCARDCONTEXT handles. DesktopSmartCardDeviceListener called
SCardGetStatusChange in a tight loop with the stale handle — WinSCard internally raises
a C++ exception (CxxThrowException) for each call, pegging a CPU core.

Fix:
- Add SCARD_E_INVALID_HANDLE, SCARD_E_SYSTEM_CANCELLED, ERROR_BROKEN_PIPE to the
  UpdateContextIfNonCritical recovery switch
- Add Thread.Sleep(1000) backoff after recovery to prevent secondary tight loop
- Guard UpdateCurrentContext against failed SCardEstablishContext
- Extract ISCardInterop interface enabling cross-platform unit tests without hardware

Tests:
- DesktopSmartCardDeviceListenerSCardErrorTests: cross-platform mock tests (Track B)
- DesktopSmartCardDeviceListenerWindowsTests: Windows CPU regression test (Track A)
  measuring TotalProcessorTime before/after handle invalidation via real WinSCard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…try/finally leak fix

- Add ArgumentNullException guard for injected ISCardInterop in internal constructor
- Check SCardReleaseContext return value in test helper and Skip on failure
- Wrap disposal test listener in try/finally to prevent resource leak on Skip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… CPM override

- Replace Assert.NotEqual(..., string) with Assert.True(..., string) — xunit 2.9.3
  has no string-message overload for NotEqual (that's xunit 3.x only)
- Add Directory.Packages.props to .gitignore (local-only workaround that prevents
  a parent project's CPM config from breaking restore in this branch)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Short-circuit CheckForUpdates after context recovery at all three
  GetStatusChange call sites to prevent stale newStates from overwriting
  the freshly refreshed _readerStates (Copilot review finding).
- Format SCARD_READER_STATE[] in diagnostic logging so individual reader
  entries are printed instead of the array type name.
- Return distinct non-zero handles from FakeSCardInterop.EstablishContext
  on success, matching real WinSCard behavior.
- Extract DRY helper for context-reestablishment test assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Elena Quijano <84402487+equijano21@users.noreply.github.com>
Co-authored-by: Elena Quijano <84402487+equijano21@users.noreply.github.com>
Co-authored-by: Elena Quijano <84402487+equijano21@users.noreply.github.com>
Bumps nginx from `e7257f1` to `645eda1`.

---
updated-dependencies:
- dependency-name: nginx
  dependency-version: alpine
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
docs: added ZeroMemory operations to additional OTP configuration examples
…cies

docs: Address inconsistencies and obsolete class references
… (YESDK-1260)

Adds integration test confirming RSA 2048 signing works over SCP03 with
transport-level command chaining. The original pipeline order (SCP encrypts
first, then CommandChaining splits the encrypted blob) is correct and no
code change is required; this test prevents future regressions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…updates

Bumps the github-actions group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.16.0` | `2.17.0` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.0` | `7.0.1` |
| [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) | `1.0.78` | `1.0.96` |
| [github/codeql-action](https://github.com/github/codeql-action) | `4.34.1` | `4.35.1` |
| [actions/create-github-app-token](https://github.com/actions/create-github-app-token) | `3.0.0` | `3.1.1` |
| [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment) | `3.0.2` | `3.0.4` |



Updates `step-security/harden-runner` from 2.16.0 to 2.17.0
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](step-security/harden-runner@fa2e9d6...f808768)

Updates `actions/upload-artifact` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@bbbca2d...043fb46)

Updates `anthropics/claude-code-action` from 1.0.78 to 1.0.96
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](anthropics/claude-code-action@0ee1bee...5fb8995)

Updates `github/codeql-action` from 4.34.1 to 4.35.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@3869755...c10b806)

Updates `actions/create-github-app-token` from 3.0.0 to 3.1.1
- [Release notes](https://github.com/actions/create-github-app-token/releases)
- [Commits](actions/create-github-app-token@f8d387b...1b10c78)

Updates `marocchino/sticky-pull-request-comment` from 3.0.2 to 3.0.4
- [Release notes](https://github.com/marocchino/sticky-pull-request-comment/releases)
- [Commits](marocchino/sticky-pull-request-comment@70d2764...0ea0beb)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.96
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-version: 4.35.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/create-github-app-token
  dependency-version: 3.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: marocchino/sticky-pull-request-comment
  dependency-version: 3.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps CommunityToolkit.Diagnostics from 8.4.1 to 8.4.2
Bumps Microsoft.Bcl.AsyncInterfaces from 10.0.5 to 10.0.6
Bumps Microsoft.Bcl.Cryptography from 10.0.5 to 10.0.6
Bumps Microsoft.CodeAnalysis.NetAnalyzers from 10.0.201 to 10.0.202
Bumps Microsoft.Extensions.Configuration.Json from 10.0.5 to 10.0.6
Bumps Microsoft.Extensions.Logging.Abstractions from 10.0.5 to 10.0.6
Bumps Microsoft.Extensions.Options.ConfigurationExtensions from 10.0.5 to 10.0.6
Bumps Microsoft.NET.Test.Sdk from 18.3.0 to 18.4.0
Bumps Microsoft.SourceLink.GitHub from 10.0.201 to 10.0.202
Bumps System.Configuration.ConfigurationManager from 10.0.5 to 10.0.6
Bumps System.Formats.Asn1 from 10.0.5 to 10.0.6
Bumps System.Formats.Cbor from 10.0.5 to 10.0.6

---
updated-dependencies:
- dependency-name: CommunityToolkit.Diagnostics
  dependency-version: 8.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: CommunityToolkit.Diagnostics
  dependency-version: 8.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: CommunityToolkit.Diagnostics
  dependency-version: 8.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: CommunityToolkit.Diagnostics
  dependency-version: 8.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Bcl.AsyncInterfaces
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Bcl.AsyncInterfaces
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Bcl.Cryptography
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: System.Formats.Asn1
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.CodeAnalysis.NetAnalyzers
  dependency-version: 10.0.202
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.CodeAnalysis.NetAnalyzers
  dependency-version: 10.0.202
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Extensions.Configuration.Json
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Extensions.Logging.Abstractions
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Extensions.Logging.Abstractions
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Extensions.Options.ConfigurationExtensions
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all_packages
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all_packages
- dependency-name: Microsoft.SourceLink.GitHub
  dependency-version: 10.0.202
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.SourceLink.GitHub
  dependency-version: 10.0.202
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: System.Configuration.ConfigurationManager
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: System.Formats.Asn1
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: System.Formats.Cbor
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
...

Signed-off-by: dependabot[bot] <support@github.com>
chore(deps): bump nginx from `e7257f1` to `645eda1`
docs: corrected info on encidentifier, added relevant info and links
dependabot Bot and others added 27 commits April 29, 2026 07:14
Bumps BenchmarkDotNet from 0.14.0 to 0.15.8
Bumps Microsoft.Extensions.Logging.Console from 10.0.5 to 10.0.7
Bumps Microsoft.NET.Test.Sdk from 18.4.0 to 18.5.1
Bumps SharpFuzz from 2.1.1 to 2.2.0

---
updated-dependencies:
- dependency-name: BenchmarkDotNet
  dependency-version: 0.15.8
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all_packages
- dependency-name: Microsoft.Extensions.Logging.Console
  dependency-version: 10.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Extensions.Logging.Console
  dependency-version: 10.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.Extensions.Logging.Console
  dependency-version: 10.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all_packages
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.5.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all_packages
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.5.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all_packages
- dependency-name: SharpFuzz
  dependency-version: 2.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all_packages
...

Signed-off-by: dependabot[bot] <support@github.com>
…actions-5b59a811ca

chore(deps): bump the github-actions group with 4 updates
…/all_packages-f36d95f5b4

Bump the all_packages group with 4 updates
…ebug

Wire-level events (per-packet timestamps, I/O callbacks, raw buffer hex,
API call success confirmations) were emitting at Information level, flooding
integration test output with hundreds of lines per ceremony.

Source changes (8 files, 13 call sites):
- LogDeviceAccessTime/UpdateLastUsed on macOS, Windows, Linux HID + SmartCard
- IOKitApiCall success in HidLoggerExtensions
- MacOSHidIOReportConnection.ReportCallback
- SensitiveLogInformation → SensitiveLogDebug for raw buffer hex in macOS
  IO/Feature and Linux IO report connections

Config changes (2 files):
- integration/appsettings.json and sandbox/appsettings.json: "Yubico": "Debug"
  → "Yubico": "Information", establishing Information as the default floor

Result: three-tier system — Information (milestones), Debug (per-packet events),
Debug + ENABLE_SENSITIVE_LOG (raw byte hex).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Yubico.NativeShims previously had zero direct test coverage. The build CI
verified the library *built*, but never executed a single exported function
or validated that the per-platform export lists matched the implementation.
This change introduces two complementary layers and a local-dev iteration
script.

Layer A — export-table sanity (CI-blocking)
  * tests/expected_symbols.txt — single source of truth: the 35 Native_*
    symbols the library MUST export (BigNum, EC, GCM, CMAC, PCSC).
  * tests/check_exports.sh — POSIX validator using nm, runs on macOS and
    Linux; cross-arch safe (nm reads ELF metadata, works on arm64 binaries
    inspected from an x86_64 host).
  * tests/check_exports.ps1 — Windows validator using dumpbin; works on
    arm64 DLLs inspected from an x64 runner.
  * .github/workflows/build-nativeshims.yml — invokes the validator after
    every per-platform build (Windows x64/x86/arm64, Linux amd64/arm64,
    macOS x64/arm64). Build fails on missing or extra Native_* symbol —
    no more shipping a binary with a quietly-dropped export.

Layer B — managed P/Invoke functional tests (runs in existing PR workflows)
  * Yubico.Core/tests/unit/Yubico/PlatformInterop/Cryptography/{BigNum,
    EcPoint,GcmEvp,Cmac}InteropTests.cs — 30 xUnit tests using public
    Known-Answer Tests cited in comments:
      - NIST SP 800-38D (AES-GCM)
      - RFC 4493 (AES-128-CMAC)
      - SEC2 v2 §2.4.2 (P-256)
    Tests exercise the actual marshaling boundary consumers depend on:
    BigNum round-trips, EC point arithmetic / scalar mul, GCM tag tamper
    detection, CMAC multi-update equivalence. All deterministic, no
    hardware dependency. Runs in <100 ms.

Local dev
  * Yubico.NativeShims/build-macOS-local.sh — bypasses vcpkg using brew
    OpenSSL@3 for fast arm64 dev rebuilds; replaces the consumed NuGet
    cache dylib in-place. Now also runs check_exports.sh against the
    fresh build for immediate parity feedback.

Verification
  * dotnet test PlatformInterop filter: 30/30 passing locally
  * expected_symbols.txt aligned with origin/develop's exports.llvm
    (35/35 match)
  * Negative test: removing Native_BN_new from expected list produces
    exit 1 with diagnostic, as designed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tion

Adds a single OpenSSL EC_POINT_is_on_curve wrapper to support ARKG-P256
input validation in Phase 3+. Untrusted public keys (pkBl, pkKem) received
from previewSign authenticator responses MUST be validated before use in
ARKG derivation to prevent invalid-curve attacks.

All 3 platform export files updated in alphabetical position. Native build
verification deferred to a follow-up step (VCPKG_INSTALLATION_ROOT not set
in this session); P/Invoke wrapper in Phase 3 will compile but will throw
EntryPointNotFoundException at runtime until the local NativeShims binary
is rebuilt and copied into ~/.nuget/packages/yubico.nativeshims/<ver>/.

Local build steps to run before Phase 3+ integration testing:
  cd Yubico.NativeShims && ./build-macOS.sh
  cp ./osx-x64/libYubico.NativeShims.dylib   \\
     ~/.nuget/packages/yubico.nativeshims/<ver>/runtimes/osx-x64/native/
  cp ./osx-arm64/libYubico.NativeShims.dylib \\
     ~/.nuget/packages/yubico.nativeshims/<ver>/runtimes/osx-arm64/native/

(VCPKG_INSTALLATION_ROOT must be set to a vcpkg source tree first.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the managed P/Invoke wrapper (NativeMethods.EcPointIsOnCurve) and
two on-curve test cases (P-256 generator on curve; bit-flipped Y off curve)
that exercise the C function exposed by the prior commit. Updates
expected_symbols.txt to include Native_EC_POINT_is_on_curve so Layer A's
check_exports validator passes against the built library.

This keeps the PR self-contained: the new export, its managed wrapper, the
canonical-list entry, and the tests covering it all land together. Consumers
of the wrapper (ArkgPrimitivesOpenSsl, etc.) live on the webauthn previewSign
branch and depend on this groundwork.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Each of the four PlatformInterop crypto test files now opens with a Purpose,
What this validates, and References block stating the standards behind every
test (NIST SP 800-38D for GCM, RFC 4493 for CMAC, SEC 1/SEC 2/FIPS 186-5 for
P-256, OpenSSL man pages for the BIGNUM API). Reviewers and future
contributors can now see at a glance why the file exists, which entry points
it pins, and where to verify the test vectors come from.

No production code or test logic changes; comment-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HKDF-SHA256 is a generic primitive that does not belong in the YubiKey
assembly. Moving it to Core enables Core-internal callers (notably the
ARKG implementation in ArkgPrimitivesOpenSsl) to share a single
canonical Span-based implementation instead of carrying a private copy.

Replaces the string-based CryptographyProviders.HmacCreator indirection
with direct BCL HMACSHA256 instantiation. The HmacCreator pattern was
not used anywhere outside HkdfUtilities for HMAC swap-ability (no test
overrides, no FIPS injection), so this removes a layer with no current
swap-need.

Bundles a security fix: the intermediate pseudo-random key from HKDF
extract is now zeroed via CryptographicOperations.ZeroMemory in a
try/finally before the function returns. Previously leaked.

Existing YubiKey callers updated to import the new namespace (AuthenticatorInfo
+ HkdfUtilitiesTests); behavior unchanged. KAT vectors verify byte-for-byte
equivalence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the test/SUT assembly mismatch left by the prior commit (75409d2)
which moved HkdfUtilities source from Yubico.YubiKey to Yubico.Core but kept
the test file in Yubico.YubiKey/tests with the namespace still pointing at
Yubico.YubiKey.Cryptography. Tests should mirror their SUT's assembly so
future refactors stay coherent.

Changes:
  * git mv Yubico.YubiKey/tests/.../HkdfUtilitiesTests.cs
        -> Yubico.Core/tests/unit/Yubico/Core/Cryptography/HkdfUtilitiesTests.cs
  * Namespace: Yubico.YubiKey.Cryptography -> Yubico.Core.Cryptography

No test logic changes. RFC 5869 KAT vectors unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix(logging): downgrade HID/SmartCard transport events from Info to Debug
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
test(core,nativeshims): export sanity + interop KATs + Hkdf relocate
Replace hard-pinned Yubico.NativeShims version with floating range 1.*-*
and enable RestorePackagesWithLockFile so the resolved version is captured
in packages.lock.json. This stops manual csproj bumps every prerelease
publish while keeping restores reproducible — the lockfile pins the
concrete version until an intentional `dotnet restore --force-evaluate`.

Verified locally:
- dotnet restore generates packages.lock.json (resolves to
  1.16.1-prerelease.20260428.1, same as previous pin).
- dotnet build Yubico.Core: 0 warnings, 0 errors across net472,
  netstandard2.0, netstandard2.1.
- dotnet build Yubico.YubiKey (downstream consumer): clean.
- Yubico.Core unit tests: 525 passed, 0 failed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Encodes the branch-based NuGet source policy in build.yml only:

* New `enforce-branch-policy` job runs first; on `refs/heads/main` it
  fails the workflow if `Yubico.Core/src/packages.lock.json` pins a
  prerelease `Yubico.NativeShims`. Other jobs `needs:` it so the
  failure surfaces with a clear message before run-tests / build-artifacts
  attempt restore.
* `build-artifacts` now uses two mutually exclusive `setup-dotnet` steps:
  non-main builds add the internal Yubico GitHub Packages feed (so
  prerelease NativeShims can resolve); main builds get nuget.org only.
* `Yubico.Core.csproj` adds `<RestoreLockedMode>` under `GITHUB_ACTIONS`
  so any CI run that drifts from the committed lockfile fails restore
  instead of silently re-floating.

Release ritual implied: before merging develop -> main, re-pin the
lockfile via `dotnet restore Yubico.Core/src/Yubico.Core.csproj
--force-evaluate` against an nuget.org-only environment, then commit
the updated `packages.lock.json`. The new guard makes that requirement
explicit instead of cryptic.

Verified locally:
- YAML parses (python yaml.safe_load).
- `GITHUB_ACTIONS=true dotnet restore` succeeds with the new
  RestoreLockedMode (lockfile is in sync).
- Guard logic rehearsed: fires on current lockfile (prerelease pinned),
  passes when version sed-replaced to a stable string.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI failure on Windows test job: NU1004 — locked-mode restore rejected the
committed lockfile because it was generated on macOS, where NuGet
implicitly adds Microsoft.NETFramework.ReferenceAssemblies (and friends)
to the net472 graph. On Windows those reference assemblies come from the
SDK install, so the implicit package isn't added; the lockfile contains
references the Windows project graph doesn't have, and locked mode hard
fails.

This is a known NuGet limitation: lockfiles are not OS-portable when
implicit/conditional packages differ between platforms.

Removing RestoreLockedMode preserves the parts of the PR that actually
satisfy the original goals:
- floating Version="1.*-*"           -> stops hand-bumping
- RestorePackagesWithLockFile=true   -> reproducible restore (lockfile
                                        still pins concrete version)
- branch-policy guard in build.yml   -> hard-fails main on prerelease
                                        Yubico.NativeShims in lockfile

To safely re-introduce locked mode in a follow-up: either generate
per-OS lockfiles on every CI matrix runner, or add explicit
<PackageReference> entries for every implicit root so all OSes resolve
identically.

Verified: GITHUB_ACTIONS=true dotnet restore now succeeds with no
lockfile delta; Yubico.Core builds clean across net472 / netstandard2.0
/ netstandard2.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brief subsection so future agents understand the float + lockfile +
branch-policy contract introduced in this PR before they edit the csproj
or the build workflow:
- Version is floating ("1.*-*") — don't hand-bump.
- Bump = --force-evaluate + commit packages.lock.json only.
- RestoreLockedMode intentionally absent (OS-portability).
- main branch CI hard-fails on prerelease lockfile pins.
- build.yml has separate setup-dotnet steps for main vs non-main.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Project-local Claude Code skill at .claude/skills/Release/ that drives
the full Yubico .NET SDK release end-to-end:

- Phase 1: Pre-flight (gh auth, recent tags, open PRs, version + date prompts)
- Phase 2: NativeShims gate — auto-detects Yubico.NativeShims/ changes
  since previous tag, dispatches build-nativeshims.yml when needed
- Phase 3: Release branch from develop + lockfile repin (--force-evaluate
  against nuget.org-only) when NativeShims rebuilt as stable + release
  notes draft from merged PRs + PR to main
- Phase 4: Wait for merge, dispatch build.yml with version input, tag
  only after CI green
- Phase 5: Sign + publish — Windows-only wizard. Detects platform; on
  non-Windows prints handoff with cached run IDs; on Windows downloads
  artifacts to ~/Releases/<version>/, runs build/sign.ps1, publishes
  to NuGet.org with live status board. NativeShims signs+publishes
  BEFORE main packages (hard ordering).
- Phase 6: Draft GitHub release with signed assets, deploy-docs trigger
- Phase 7: Merge main back to develop, generate Slack #ask-tla
  announcement in canonical emoji format from prior 1.15.1 precedent

Supports cross-machine resume via ~/Releases/<version>/.state.json:
start phases 1-4 on macOS/Linux, finish phase 5+ with /Release resume
<version> on Windows.

Note: file added with `git add -f` because .gitignore [Rr]elease/
pattern (intended for .NET build output) collaterally matches the
skill's Release/ directory name.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Applied all 12 Copilot review comments on PR #475:

SKILL.md / DropRelease.md:
- Replace "Dennis" with "the operator" / "the release operator" so the
  skill is reusable by any release engineer, not personalized
- Add `misc` bucket to state.categorizedPRs schema and Slack draft so
  Miscellaneous PRs are never dropped (new emoji: 🧰📌)
- Document date storage convention: ISO YYYY-MM-DD in state, formatted
  display string derived at write time (whats-new.md / Slack)
- Renumber Phase 3 steps (had two "4." entries) — now 1..10 sequential
- Specify exact PR-body-file generation in Phase 3 step 9: awk extracts
  just the new `### <version>` section into a real temp file
- Make Phase 5 non-Windows handoff text conditional on actual state
  (entry path A: NativeShims-only / entry path B: full release) instead
  of hardcoding "past CI green and tagged"
- Fix Invoke-NuGetPackagePush invocation to match build/sign.ps1
  signature: -PackagePath (mandatory) + -ApiKey/$env:NUGET_API_KEY
  fallback + -SkipDuplicate; was incorrectly using -WorkingDirectory
- Fill in Phase 5e publish call (was left as ellipsis)
- Replace bash process substitution `<(extract ...)` in Phase 6 with
  cross-platform temp file approach: bash awk + PowerShell variants

.gitignore:
- Add `!.claude/skills/Release/` exception so Release skill files are
  no longer swallowed by [Rr]elease/ pattern (intended for .NET
  bin/Release output). Removes the need for `git add -f`.
chore(claude): add /Release skill for SDK release automation
FIDO2 tests fail with a cryptic SCARD_E_NO_ACCESS error when the test
host isn't running as Administrator on Windows. This adds an early
Skip.If guard in the base class constructor so all FIDO2 session tests
fail with a clear message instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@DennisDyallo DennisDyallo merged commit 29d38c6 into main Apr 29, 2026
6 of 7 checks passed
@DennisDyallo DennisDyallo deleted the release/1.16.1 branch April 29, 2026 20:21
@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Branch Rate Complexity Health
Yubico.Core 53% 48% 1584
Yubico.YubiKey 50% 45% 7180
Summary 51% (12922 / 25583) 46% (3162 / 6912) 8764

Minimum allowed line rate is 40%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants