peass-ng/PEASS-ng · error · IOException
malformed BMPString encoding encountered
Error message
malformed BMPString encoding encountered
What it means
GetBmpCharBuffer requires BMPString contents to be an even number of bytes, since each character is encoded as 2 bytes (UCS-2). An odd remaining byte count means the encoding is malformed, so an IOException is thrown.
Source
Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/asn1/Asn1InputStream.cs:334
return defIn.ToArray();
}
byte[] buf = tmpBuffers[len];
if (buf == null)
{
buf = tmpBuffers[len] = new byte[len];
}
defIn.ReadAllIntoByteArray(buf);
return buf;
}
private static char[] GetBmpCharBuffer(DefiniteLengthInputStream defIn)
{
int remainingBytes = defIn.Remaining;
if (0 != (remainingBytes & 1))
throw new IOException("malformed BMPString encoding encountered");
char[] str = new char[remainingBytes / 2];
int stringPos = 0;
byte[] buf = new byte[8];
while (remainingBytes >= 8)
{
if (Streams.ReadFully(defIn, buf, 0, 8) != 8)
throw new EndOfStreamException("EOF encountered in middle of BMPString");
str[stringPos] = (char)((buf[0] << 8) | (buf[1] & 0xFF));
str[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
str[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
str[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
stringPos += 4;
remainingBytes -= 8;
}
if (remainingBytes > 0)View on GitHub (pinned to 53fb989abc)
Solutions
- Verify the DER encoding: BMPString length field must be even and match the actual byte count
- Re-encode the string with a correct encoder (DerBmpString) instead of manual byte assembly
- Check for bit-level corruption in the source data; re-obtain from a trusted source
- Catch IOException and report the specific certificate/field as malformed
Example fix
// before
byte[] bad = Encoding.Unicode.GetBytes("CN"); // truncated by 1 byte upstream
// after
Asn1Object bmp = new DerBmpString("CN"); // let the library encode
byte[] der = bmp.GetDerEncoded(); Defensive patterns
Strategy: validation
Validate before calling
static bool BmpStringLengthIsEven(byte[] der)
{
// locate a primitive BMPString (tag 0x1E) and check its content length parity
for (int i = 0; i + 1 < der.Length; i++)
{
if (der[i] == 0x1e)
{
int lb = der[i + 1];
return (lb & 1) == 0;
}
}
return true; // no BMPString found
} Try / catch
try { Asn1Object o = Asn1Object.FromByteArray(data); }
catch (IOException ex) when (ex.Message.Contains("BMPString"))
{
// malformed BMPString encoding
} Prevention
- Use DerBmpString to encode instead of manual byte assembly
- Remember BMPString is UCS-2: content length must be even
- Re-obtain data if certificates show corruption in name fields
When it happens
Trigger: Parsing a primitive BMPString (tag 0x1E) whose definite length is odd, e.g. corrupt DER or hand-assembled bytes with a wrong length field.
Common situations: Corrupted certificates where the BMPString (often used in certificate subject/issuer fields) length byte was damaged; buggy encoders writing byte-count instead of char-count; manually constructed ASN.1 test data.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- malformed BMPString encoding encountered
- unknown object encountered in constructed OCTET STRING:
- unknown tag {tagNo} encountered
- indefinite-length primitive encoding encountered
- DER length more than 4 bytes:
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/0c75f6691ace095b.
Report an issue: GitHub.