Skip to content

Reject empty extension sequences and generalize input-stream limit detection#143

Merged
Xor-el merged 1 commit into
masterfrom
enhancements/asn1-minseqsize-and-stream-available
Jul 10, 2026
Merged

Reject empty extension sequences and generalize input-stream limit detection#143
Xor-el merged 1 commit into
masterfrom
enhancements/asn1-minseqsize-and-stream-available

Conversation

@Xor-el

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

Copy link
Copy Markdown
Owner

Two independent ASN.1 hardening changes.

  1. Minimum sequence-size restriction on X.509 extensions TCrlDistPoint and TExtendedKeyUsage now reject an empty sequence (< 1 element) in both their decode (IAsn1Sequence) and array constructors, via TAsn1Utilities.CheckSequenceSize(seq, 1, Int32.MaxValue). A malformed extension with no elements now raises EArgumentCryptoLibException instead of constructing a degenerate object. Both classes already stored the sequence and mapped on demand, so no storage change was needed. Adds TestCrlDistPointRejectsEmptySequence and TestExtendedKeyUsageRejectsEmptySequence to X509ExtensionsTests.

  2. TStreamUtilities.TryGetAvailable and use in FindLimit Add TryGetAvailable(stream, out available): best-effort remaining bytes for a seekable stream (Max(0, Size - Position)), guarded so a stream that throws is treated as unavailable. TAsn1InputStream.FindLimit now uses it, replacing the TFixedBufferStream-specific branch (GetFixedBufferStreamLimit removed): any seekable stream gets an available-based limit, not just the fixed buffer. TFixedBufferStream is seekable, so its limit is unchanged; byte-array input still yields a tight bound.

    Corrects the InputStreamTests dummy: it modelled "unknown/non-seekable" but its Seek was a no-op returning 0, making it look like a seekable empty stream. It now inherits TBaseInputStream (CanSeek = False) with a raising Seek, so it honestly exercises FindLimit's fallback; TestNegativeMaxLimitClampsFindLimit uses it to actually reach the clamp path.

…tection

Two independent ASN.1 hardening changes.

1. Minimum sequence-size restriction on X.509 extensions
   TCrlDistPoint and TExtendedKeyUsage now reject an empty sequence (< 1
   element) in both their decode (IAsn1Sequence) and array constructors, via
   TAsn1Utilities.CheckSequenceSize(seq, 1, Int32.MaxValue). A malformed
   extension with no elements now raises EArgumentCryptoLibException instead of
   constructing a degenerate object. Both classes already stored the sequence
   and mapped on demand, so no storage change was needed.
   Adds TestCrlDistPointRejectsEmptySequence and
   TestExtendedKeyUsageRejectsEmptySequence to X509ExtensionsTests.

2. TStreamUtilities.TryGetAvailable and use in FindLimit
   Add TryGetAvailable(stream, out available): best-effort remaining bytes for a
   seekable stream (Max(0, Size - Position)), guarded so a stream that throws is
   treated as unavailable. TAsn1InputStream.FindLimit now uses it, replacing the
   TFixedBufferStream-specific branch (GetFixedBufferStreamLimit removed): any
   seekable stream gets an available-based limit, not just the fixed buffer.
   TFixedBufferStream is seekable, so its limit is unchanged; byte-array input
   still yields a tight bound.

   Corrects the InputStreamTests dummy: it modelled "unknown/non-seekable" but
   its Seek was a no-op returning 0, making it look like a seekable empty stream.
   It now inherits TBaseInputStream (CanSeek = False) with a raising Seek, so it
   honestly exercises FindLimit's fallback; TestNegativeMaxLimitClampsFindLimit
   uses it to actually reach the clamp path.
@Xor-el Xor-el merged commit d0af4db into master Jul 10, 2026
24 checks passed
@Xor-el Xor-el deleted the enhancements/asn1-minseqsize-and-stream-available branch July 10, 2026 15:48
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