shadow1ng/fscan · error
BER length may be 1 or 2
Error message
BER length may be 1 or 2
What it means
ReadLength decodes a BER length field. If the high-bit short/long form indicates a long length, this implementation only supports 1- or 2-byte length encodings; any other long-form size byte is rejected with this error. It guards against encodings the parser cannot handle.
Source
Thrown at libs/grdp/protocol/t125/ber/ber.go:85
func ReadLength(r io.Reader) (int, error) {
ret := 0
size, _ := core.ReadUInt8(r)
if size&0x80 > 0 {
size = size &^ 0x80
if size == 1 {
r, err := core.ReadUInt8(r)
if err != nil {
return 0, err
}
ret = int(r)
} else if size == 2 {
r, err := core.ReadUint16BE(r)
if err != nil {
return 0, err
}
ret = int(r)
} else {
return 0, errors.New("BER length may be 1 or 2")
}
} else {
ret = int(size)
}
return ret, nil
}
func WriteLength(size int, w io.Writer) {
if size > 0x7f {
core.WriteUInt8(0x82, w)
core.WriteUInt16BE(uint16(size), w)
} else {
core.WriteUInt8(uint8(size), w)
}
}
func ReadInteger(r io.Reader) (int, error) {
if !ReadUniversalTag(TAG_INTEGER, false, r) {View on GitHub (pinned to 95cc12e753)
Solutions
- Extend ReadLength to handle 3- and 4-byte long-form lengths (0x83/0x84) if the server sends large payloads
- Capture the response bytes and confirm the length encoding; verify against BER DER rules
- Check for stream desync in preceding fields that would misalign the length byte
- Reduce certificate size or server response bulk if a 3-byte length is genuinely required
Example fix
// before
} else {
return 0, errors.New("BER length may be 1 or 2")
}
// after
} else if size == 0x83 {
r16, err := core.ReadUint16BE(r)
if err != nil {
return 0, err
}
r8, err := core.ReadUInt8(r)
if err != nil {
return 0, err
}
ret = int(r16)<<8 + int(r8)
} else {
return 0, fmt.Errorf("BER length may be 1 or 2, got 0x%02X", size)
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-scan the length byte yourself if you control framing
sizeByte := buf[pos]
if sizeByte&0x80 != 0 && (sizeByte&0x7F) > 2 {
return errors.New("server uses unsupported 3+ byte BER length")
} Try / catch
n, err := ber.ReadLength(r)
if err != nil {
if strings.Contains(err.Error(), "BER length may be 1 or 2") {
return fmt.Errorf("server BER encoding too large for this parser; patch ReadLength: %w", err)
}
return err
} Prevention
- Prefer servers sending compact DER encodings (short-form lengths)
- Patch ReadLength to support 3/4-byte lengths if connecting to servers with large payloads
- Check for upstream desync that misreads content as a length byte
When it happens
Trigger: Any BER read (ReadEnumerated, ReadInteger, ReadApplicationTag, ReadDomainParameters, ReadConnectResponse) whose length byte uses the long form with a size selector other than 1 or 2 (e.g. 0x83 = 3-byte length) or corrupted length bytes.
Common situations: Large CONNECT_RESPONSE payloads (big certificate chains) encoded with 3+ byte lengths; desynced streams where a content byte is misread as a length; nonstandard server encoders.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- enumerate size is wrong, get %v, expect 1
- wrong size
- invalid ber tag
- Bad integer tag
- ReadApplicationTag invalid data
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/c0c9fc3ba63c303e.
Report an issue: GitHub.