peass-ng/PEASS-ng · error · InvalidOperationException

attempt to get non-octet aligned data from BIT STRING

Error message

attempt to get non-octet aligned data from BIT STRING

What it means

GetOctets() returns the raw octets of a BIT STRING and is only meaningful when the string is octet-aligned (no partial bits in the last byte). If mPadBits != 0 the last byte contains trailing padding bits, so returning the bytes would expose garbage; the method throws InvalidOperationException.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/asn1/DerBitString.cs:149

        }

        public DerBitString(
            Asn1Encodable obj)
            : this(obj.GetDerEncoded())
        {
        }

        /**
         * Return the octets contained in this BIT STRING, checking that this BIT STRING really
         * does represent an octet aligned string. Only use this method when the standard you are
         * following dictates that the BIT STRING will be octet aligned.
         *
         * @return a copy of the octet aligned data.
         */
        public virtual byte[] GetOctets()
        {
            if (mPadBits != 0)
                throw new InvalidOperationException("attempt to get non-octet aligned data from BIT STRING");

            return Arrays.Clone(mData);
        }

        public virtual byte[] GetBytes()
        {
            byte[] data = Arrays.Clone(mData);

            // DER requires pad bits be zero
            if (mPadBits > 0)
            {
                data[data.Length - 1] &= (byte)(0xFF << mPadBits);
            }

            return data;
        }

        public virtual int PadBits

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Call GetBytes() instead — it returns the full content including padding bits.
  2. Check the PadBits property; if nonzero, mask the last byte with (byte)(0xFF << padBits) or use GetBytes().
  3. If you control the encoder, write octet-aligned data with padBits 0 so GetOctets() is valid.

Example fix

// before
byte[] octets = bitString.GetOctets();
// after
byte[] octets = bitString.PadBits == 0 ? bitString.GetOctets() : bitString.GetBytes();
Defensive patterns

Strategy: type-guard

Validate before calling

if (bitString.PadBits != 0) { /* use GetBytes() or mask last byte */ }

Type guard

static bool IsOctetAligned(DerBitString bs) => bs.PadBits == 0;

Try / catch

try { octets = bs.GetOctets(); }
catch (InvalidOperationException) { octets = bs.GetBytes(); /* padded: use GetBytes */ }

Prevention

When it happens

Trigger: Calling GetOctets() on a DerBitString parsed from a certificate (e.g. key usage, unique identifier, signature bits) whose stored padBits is nonzero — typically a bit string that is not a whole number of bytes.

Common situations: Reading X.509 extensions like KeyUsage or CRL distribution points that are encoded as BIT STRINGs with padding; assuming all BIT STRINGs from ASN.1 parsing are byte-aligned.

Related errors


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