Skip to content

Fix thread-safety issue in IndirectSignatureFactory hash computation#192

Merged
JeromySt merged 4 commits intomainfrom
fix/thread-safe-hash-algorithm
Apr 7, 2026
Merged

Fix thread-safety issue in IndirectSignatureFactory hash computation#192
JeromySt merged 4 commits intomainfrom
fix/thread-safe-hash-algorithm

Conversation

@JeromySt
Copy link
Copy Markdown
Member

@JeromySt JeromySt commented Apr 7, 2026

Summary

Fixes #191IndirectSignatureFactory.InternalHashAlgorithm is not thread-safe and throws CryptographicException under concurrent usage.

Problem

The IndirectSignatureFactory class caches a single HashAlgorithm instance (InternalHashAlgorithm) and reuses it across all ComputeHash calls. HashAlgorithm.ComputeHash() is not thread-safe, causing CryptographicException: Concurrent operations from multiple threads on this type are not supported. under high concurrency.

Fix

  • Added a CreateHashAlgorithm() helper method that creates a fresh HashAlgorithm instance per call
  • Replaced all InternalHashAlgorithm.ComputeHash() calls in Direct, CoseHashEnvelope, and their async variants with using blocks that create and dispose thread-local instances
  • The cached InternalHashAlgorithm is retained for the public HashAlgorithm property and HashSize computation (backward compatible)

Testing

  • Added ConcurrentHashComputationShouldNotThrow — hammers the factory with Parallel.For from many threads
  • Added ConcurrentAsyncHashComputationShouldNotThrow — launches many concurrent async tasks
  • Both tests verify results are valid indirect signatures

All 99 existing tests continue to pass.

InternalHashAlgorithm is a shared instance cached in the factory. HashAlgorithm.ComputeHash()
is not thread-safe and throws CryptographicException under concurrent usage. The fix creates
a fresh HashAlgorithm instance per ComputeHash call via a CreateHashAlgorithm() helper method,
ensuring thread safety without contention.

Added regression tests that exercise the factory from multiple threads concurrently to validate
both sync and async code paths.

Fixes #191

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CoseX509Thumprint cached a shared HashAlgorithm instance (Hasher) and reused it in
Match(), which is not thread-safe under concurrent calls. Replaced with per-call
CreateHashAlgorithm() that returns fresh disposable instances, matching the same
pattern used for the IndirectSignatureFactory fix.

Added concurrent Match and construction regression tests.

Related to #191

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread CoseIndirectSignature/IndirectSignatureFactory.Direct.cs
Comment thread CoseIndirectSignature/IndirectSignatureFactory.cs Outdated
Jstatia and others added 2 commits April 7, 2026 13:47
…tance from property

Per review feedback, removed the cached InternalHashAlgorithm field entirely.
The public HashAlgorithm property now returns a fresh instance per access via
CreateHashAlgorithm(), preserving the public contract while eliminating the
thread-unsafe shared state. HashLength and InternalCoseHashAlgorithm are now
derived from HashAlgorithmName via static helpers. Dispose is now a no-op since
there are no cached resources to release.

CoseHashV path (obsoleted) is already safe — its constructors create their own
using HashAlgorithm instances internally.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The HashValue property setter created a HashAlgorithm via
GetHashAlgorithmFromCoseHashAlgorithm for length validation but never
disposed it. Added using to ensure proper cleanup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JeromySt JeromySt merged commit 1d6b22e into main Apr 7, 2026
11 checks passed
@JeromySt JeromySt deleted the fix/thread-safe-hash-algorithm branch April 7, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IndirectSignatureFactory.InternalHashAlgorithm is not thread-safe and throws exception during cases under high concurrency usage

4 participants