mirror of
				https://github.com/yv1ing/ShotRDP.git
				synced 2025-09-16 15:10:57 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			190 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package ber
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 
 | |
| 	"ShotRDP/grdp/core"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	CLASS_MASK uint8 = 0xC0
 | |
| 	CLASS_UNIV       = 0x00
 | |
| 	CLASS_APPL       = 0x40
 | |
| 	CLASS_CTXT       = 0x80
 | |
| 	CLASS_PRIV       = 0xC0
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	PC_MASK      uint8 = 0x20
 | |
| 	PC_PRIMITIVE       = 0x00
 | |
| 	PC_CONSTRUCT       = 0x20
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	TAG_MASK            uint8 = 0x1F
 | |
| 	TAG_BOOLEAN               = 0x01
 | |
| 	TAG_INTEGER               = 0x02
 | |
| 	TAG_BIT_STRING            = 0x03
 | |
| 	TAG_OCTET_STRING          = 0x04
 | |
| 	TAG_OBJECT_IDENFIER       = 0x06
 | |
| 	TAG_ENUMERATED            = 0x0A
 | |
| 	TAG_SEQUENCE              = 0x10
 | |
| 	TAG_SEQUENCE_OF           = 0x10
 | |
| )
 | |
| 
 | |
| func berPC(pc bool) uint8 {
 | |
| 	if pc {
 | |
| 		return PC_CONSTRUCT
 | |
| 	}
 | |
| 	return PC_PRIMITIVE
 | |
| }
 | |
| 
 | |
| func ReadEnumerated(r io.Reader) (uint8, error) {
 | |
| 	if !ReadUniversalTag(TAG_ENUMERATED, false, r) {
 | |
| 		return 0, errors.New("invalid ber tag")
 | |
| 	}
 | |
| 	length, err := ReadLength(r)
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 	if length != 1 {
 | |
| 		return 0, errors.New(fmt.Sprintf("enumerate size is wrong, get %v, expect 1", length))
 | |
| 	}
 | |
| 	return core.ReadUInt8(r)
 | |
| }
 | |
| 
 | |
| func ReadUniversalTag(tag uint8, pc bool, r io.Reader) bool {
 | |
| 	bb, _ := core.ReadUInt8(r)
 | |
| 	return bb == (CLASS_UNIV|berPC(pc))|(TAG_MASK&tag)
 | |
| }
 | |
| 
 | |
| func WriteUniversalTag(tag uint8, pc bool, w io.Writer) {
 | |
| 	core.WriteUInt8((CLASS_UNIV|berPC(pc))|(TAG_MASK&tag), w)
 | |
| }
 | |
| 
 | |
| 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) {
 | |
| 		return 0, errors.New("Bad integer tag")
 | |
| 	}
 | |
| 	size, _ := ReadLength(r)
 | |
| 	switch size {
 | |
| 	case 1:
 | |
| 		num, _ := core.ReadUInt8(r)
 | |
| 		return int(num), nil
 | |
| 	case 2:
 | |
| 		num, _ := core.ReadUint16BE(r)
 | |
| 		return int(num), nil
 | |
| 	case 3:
 | |
| 		integer1, _ := core.ReadUInt8(r)
 | |
| 		integer2, _ := core.ReadUint16BE(r)
 | |
| 		return int(integer2) + int(integer1<<16), nil
 | |
| 	case 4:
 | |
| 		num, _ := core.ReadUInt32BE(r)
 | |
| 		return int(num), nil
 | |
| 	default:
 | |
| 		return 0, errors.New("wrong size")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WriteInteger(n int, w io.Writer) {
 | |
| 	WriteUniversalTag(TAG_INTEGER, false, w)
 | |
| 	if n <= 0xff {
 | |
| 		WriteLength(1, w)
 | |
| 		core.WriteUInt8(uint8(n), w)
 | |
| 	} else if n <= 0xffff {
 | |
| 		WriteLength(2, w)
 | |
| 		core.WriteUInt16BE(uint16(n), w)
 | |
| 	} else {
 | |
| 		WriteLength(4, w)
 | |
| 		core.WriteUInt32BE(uint32(n), w)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WriteOctetstring(str string, w io.Writer) {
 | |
| 	WriteUniversalTag(TAG_OCTET_STRING, false, w)
 | |
| 	WriteLength(len(str), w)
 | |
| 	core.WriteBytes([]byte(str), w)
 | |
| }
 | |
| 
 | |
| func WriteBoolean(b bool, w io.Writer) {
 | |
| 	bb := uint8(0)
 | |
| 	if b {
 | |
| 		bb = uint8(0xff)
 | |
| 	}
 | |
| 	WriteUniversalTag(TAG_BOOLEAN, false, w)
 | |
| 	WriteLength(1, w)
 | |
| 	core.WriteUInt8(bb, w)
 | |
| }
 | |
| 
 | |
| func ReadApplicationTag(tag uint8, r io.Reader) (int, error) {
 | |
| 	bb, _ := core.ReadUInt8(r)
 | |
| 	if tag > 30 {
 | |
| 		if bb != (CLASS_APPL|PC_CONSTRUCT)|TAG_MASK {
 | |
| 			return 0, errors.New("ReadApplicationTag invalid data")
 | |
| 		}
 | |
| 		bb, _ := core.ReadUInt8(r)
 | |
| 		if bb != tag {
 | |
| 			return 0, errors.New("ReadApplicationTag bad tag")
 | |
| 		}
 | |
| 	} else {
 | |
| 		if bb != (CLASS_APPL|PC_CONSTRUCT)|(TAG_MASK&tag) {
 | |
| 			return 0, errors.New("ReadApplicationTag invalid data2")
 | |
| 		}
 | |
| 	}
 | |
| 	return ReadLength(r)
 | |
| }
 | |
| 
 | |
| func WriteApplicationTag(tag uint8, size int, w io.Writer) {
 | |
| 	if tag > 30 {
 | |
| 		core.WriteUInt8((CLASS_APPL|PC_CONSTRUCT)|TAG_MASK, w)
 | |
| 		core.WriteUInt8(tag, w)
 | |
| 		WriteLength(size, w)
 | |
| 	} else {
 | |
| 		core.WriteUInt8((CLASS_APPL|PC_CONSTRUCT)|(TAG_MASK&tag), w)
 | |
| 		WriteLength(size, w)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func WriteEncodedDomainParams(data []byte, w io.Writer) {
 | |
| 	WriteUniversalTag(TAG_SEQUENCE, true, w)
 | |
| 	WriteLength(len(data), w)
 | |
| 	core.WriteBytes(data, w)
 | |
| }
 |