peass-ng/PEASS-ng · error · IOException

cannot recognise object in stream

Error message

cannot recognise object in stream

What it means

Asn1Object.FromStream wraps Asn1InputStream.ReadObject and converts any InvalidCastException bubbling out of parsing into an IOException with this message. It means the stream contained bytes whose decoded ASN.1 object could not be cast to a recognized Asn1Object, i.e. the data is not a valid/complete DER or BER structure the library understands.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/asn1/Asn1Object.cs:46

			{
				throw new IOException("cannot recognise object in byte array");
			}
		}

		/// <summary>Read a base ASN.1 object from a stream.</summary>
		/// <param name="inStr">The stream to parse.</param>
		/// <returns>The base ASN.1 object represented by the byte array.</returns>
		/// <exception cref="IOException">If there is a problem parsing the data.</exception>
		public static Asn1Object FromStream(
			Stream inStr)
		{
			try
			{
				return new Asn1InputStream(inStr).ReadObject();
			}
			catch (InvalidCastException)
			{
				throw new IOException("cannot recognise object in stream");
			}
		}

		public sealed override Asn1Object ToAsn1Object()
		{
			return this;
		}

		internal abstract void Encode(DerOutputStream derOut);

		protected abstract bool Asn1Equals(Asn1Object asn1Object);
		protected abstract int Asn1GetHashCode();

		internal bool CallAsn1Equals(Asn1Object obj)
		{
			return Asn1Equals(obj);
		}

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Verify the input is genuine DER/BER (hexdump first bytes: valid SEQUENCE starts 0x30 ...)
  2. If input is PEM, strip the -----BEGIN/END----- armor and base64-decode before FromStream
  3. Wrap in try/catch for IOException and fail gracefully / surface a 'not valid ASN.1' message to the caller
  4. Regenerate or re-export the file from its source; check for truncation during transfer

Example fix

// before
Asn1Object obj = Asn1Object.FromStream(stream);
// after
byte[] der = Convert.FromBase64String(pemBody); // if PEM
using (var ms = new MemoryStream(der))
{
    try { Asn1Object obj = Asn1Object.FromStream(ms); }
    catch (IOException) { /* not valid ASN.1 data */ }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify plausible DER header before parsing
byte[] head = new byte[2];
if (stream is MemoryStream ms && ms.Length >= 2 && (ms.ToArray()[0] & 0x1f) != 0) { /* plausible */ }

Type guard

bool IsPlausibleDer(Stream s) { if (!s.CanRead) return false; int b = s.ReadByte(); s.Position -= 1; return b == 0x30 || b == 0x31 || (b & 0x1f) != 0 && (b & 0xc0) != 0; }

Try / catch

try { var obj = Asn1Object.FromStream(stream); }
catch (IOException ex) { log.Warn("stream is not valid ASN.1: " + ex.Message); return null; }

Prevention

When it happens

Trigger: Calling Asn1Object.FromStream on a stream whose first object decodes to an internal type that fails the cast to Asn1Object — typically truncated, garbage, or non-ASN.1 bytes at the start of the stream.

Common situations: Parsing a certificate, key file, or PKCS#7 blob that is actually base64 text, a PEM header, or raw binary that is not ASN.1; feeding a truncated DER file; passing the wrong stream (e.g. decrypted-wrong bytes after bad key derivation).

Related errors


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/9d3186e07efb6c17. Report an issue: GitHub.