Skip to content

Remove HashLib IHash leak from public IDigest#126

Merged
Xor-el merged 1 commit into
masterfrom
refactor/digest-backing-hash-capability
Jul 1, 2026
Merged

Remove HashLib IHash leak from public IDigest#126
Xor-el merged 1 commit into
masterfrom
refactor/digest-backing-hash-capability

Conversation

@Xor-el

@Xor-el Xor-el commented Jul 1, 2026

Copy link
Copy Markdown
Owner

IDigest is an adapter over HashLib4Pascal's IHash, but it re-exposed that IHash on its public contract via GetUnderlyingHasher/UnderlyingHasher. That baked HashLib into the public digest API (ClpIDigest.pas itself used HlpIHash) and advertised a capability not every digest has - TPrehash returned nil, so building an HMAC from a prehash digest passed nil into HashLib and crashed cryptically.

Move the raw-hash access off IDigest onto a small internal capability interface, IBackingHashProvider (property BackingHash), implemented by TDigest. The public IDigest is now HashLib-free.

  • New ClpIBackingHashProvider.pas; IDigest drops GetUnderlyingHasher and its HlpIHash dependency.
  • TDigest implements IBackingHashProvider (GetUnderlyingHasher -> GetBackingHash); TPrehash's override still returns nil.
  • THMac and TPkcs5S2ParametersGenerator obtain the hash via Supports(digest, IBackingHashProvider, p) then p.BackingHash, raising a clear "digest does not provide a backing hash" error when it is nil/absent (fixes the prehash nil footgun).
  • TDsaParametersGenerator replaces the hasher is TSHA1 type check with AlgorithmName = 'SHA-1', dropping the HlpSHA1 import.

IDigest is an adapter over HashLib4Pascal's IHash, but it re-exposed that
IHash on its public contract via GetUnderlyingHasher/UnderlyingHasher. That
baked HashLib into the public digest API (ClpIDigest.pas itself used HlpIHash)
and advertised a capability not every digest has - TPrehash returned nil, so
building an HMAC from a prehash digest passed nil into HashLib and crashed
cryptically.

Move the raw-hash access off IDigest onto a small internal capability interface,
IBackingHashProvider (property BackingHash), implemented by TDigest. The public
IDigest is now HashLib-free.

- New ClpIBackingHashProvider.pas; IDigest drops GetUnderlyingHasher and its
  HlpIHash dependency.
- TDigest implements IBackingHashProvider (GetUnderlyingHasher -> GetBackingHash);
  TPrehash's override still returns nil.
- THMac and TPkcs5S2ParametersGenerator obtain the hash via
  Supports(digest, IBackingHashProvider, p) then p.BackingHash, raising a clear
  "digest does not provide a backing hash" error when it is nil/absent (fixes the
  prehash nil footgun).
- TDsaParametersGenerator replaces the `hasher is TSHA1` type check with
  AlgorithmName = 'SHA-1', dropping the HlpSHA1 import.
@Xor-el Xor-el merged commit 6f24bb1 into master Jul 1, 2026
24 checks passed
@Xor-el Xor-el deleted the refactor/digest-backing-hash-capability branch July 1, 2026 10:36
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.

1 participant