{"record":{"id":"c0c9fc3ba63c303e","repo":"shadow1ng/fscan","slug":"ber-length-may-be-1-or-2","errorCode":null,"errorMessage":"BER length may be 1 or 2","messagePattern":"BER length may be 1 or 2","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/grdp/protocol/t125/ber/ber.go","lineNumber":85,"sourceCode":"func ReadLength(r io.Reader) (int, error) {\n\tret := 0\n\tsize, _ := core.ReadUInt8(r)\n\tif size&0x80 > 0 {\n\t\tsize = size &^ 0x80\n\t\tif size == 1 {\n\t\t\tr, err := core.ReadUInt8(r)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tret = int(r)\n\t\t} else if size == 2 {\n\t\t\tr, err := core.ReadUint16BE(r)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tret = int(r)\n\t\t} else {\n\t\t\treturn 0, errors.New(\"BER length may be 1 or 2\")\n\t\t}\n\t} else {\n\t\tret = int(size)\n\t}\n\treturn ret, nil\n}\n\nfunc WriteLength(size int, w io.Writer) {\n\tif size > 0x7f {\n\t\tcore.WriteUInt8(0x82, w)\n\t\tcore.WriteUInt16BE(uint16(size), w)\n\t} else {\n\t\tcore.WriteUInt8(uint8(size), w)\n\t}\n}\n\nfunc ReadInteger(r io.Reader) (int, error) {\n\tif !ReadUniversalTag(TAG_INTEGER, false, r) {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/libs/grdp/protocol/t125/ber/ber.go#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n} else {\n    return 0, errors.New(\"BER length may be 1 or 2\")\n}\n\n// after\n} else if size == 0x83 {\n    r16, err := core.ReadUint16BE(r)\n    if err != nil {\n        return 0, err\n    }\n    r8, err := core.ReadUInt8(r)\n    if err != nil {\n        return 0, err\n    }\n    ret = int(r16)<<8 + int(r8)\n} else {\n    return 0, fmt.Errorf(\"BER length may be 1 or 2, got 0x%02X\", size)\n}","handlingStrategy":"try-catch","validationCode":"// pre-scan the length byte yourself if you control framing\nsizeByte := buf[pos]\nif sizeByte&0x80 != 0 && (sizeByte&0x7F) > 2 {\n    return errors.New(\"server uses unsupported 3+ byte BER length\")\n}","typeGuard":null,"tryCatchPattern":"n, err := ber.ReadLength(r)\nif err != nil {\n    if strings.Contains(err.Error(), \"BER length may be 1 or 2\") {\n        return fmt.Errorf(\"server BER encoding too large for this parser; patch ReadLength: %w\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["rdp","ber","asn1","length-mismatch"],"backgroundTag":"unsupported-operation","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}