lic

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package lic implements RDP licensing PDU handling (MS-RDPBCGR section 2.2.1.12).

Index

Constants

View Source
const (
	LicenseRequest            byte = 0x01
	PlatformChallenge         byte = 0x02
	NewLicense                byte = 0x03
	UpgradeLicense            byte = 0x04
	LicenseInfo               byte = 0x12
	NewLicenseRequest         byte = 0x13
	PlatformChallengeResponse byte = 0x15
	ErrorAlert                byte = 0xFF
)

Licensing message types

View Source
const (
	ErrInvalidServerCertificate uint32 = 0x00000001
	ErrNoLicense                uint32 = 0x00000002
	ErrInvalidScope             uint32 = 0x00000004
	ErrInvalidMac               uint32 = 0x00000003
	StatusValidClient           uint32 = 0x00000007
)

Licensing error codes

View Source
const (
	STTotalAbort        uint32 = 0x00000001
	STNoTransition      uint32 = 0x00000002
	STResetPhaseToStart uint32 = 0x00000003
	STResendLastMessage uint32 = 0x00000004
)

Licensing state transition codes

View Source
const (
	PreambleVersion20 byte = 0x02
	PreambleVersion30 byte = 0x03
)

Preamble flags

View Source
const (
	BBDataBlob        uint16 = 0x0001
	BBRandomBlob      uint16 = 0x0002
	BBCertificateBlob uint16 = 0x0003
	BBErrorBlob       uint16 = 0x0004
	BBEncryptedBlob   uint16 = 0x0009
	BBKeyExchAlgBlob  uint16 = 0x000D
	BBScopeBlob       uint16 = 0x000E
	BBAnyBlob         uint16 = 0xFFFF
)

Blob type constants (MS-RDPELE 2.2.1.12.1.2)

View Source
const (
	// ClientOSID = WINDOWS(0x04) << 8 shifted into high word
	PlatformIDWindows uint32 = 0x04000000
	// ISV = 0x00010000
	PlatformISV uint32 = 0x00010000
	// Combined typical client platform ID
	ClientPlatformID uint32 = 0x04000401
)

Platform ID constants

View Source
const (
	KeyExchAlgRSA uint32 = 0x00000001
)

Key exchange algorithm

Variables

This section is empty.

Functions

func EncodeBlob

func EncodeBlob(b Blob) []byte

EncodeBlob serializes a LICENSE_BINARY_BLOB.

func EncodeNewLicenseRequest

func EncodeNewLicenseRequest(clientRandom, encryptedPreMaster []byte, username, hostname string) []byte

EncodeNewLicenseRequest builds a CLIENT_NEW_LICENSE_REQUEST PDU (including preamble).

Layout: Preamble(4) + KeyExchangeAlg(u32) + PlatformId(u32) + ClientRandom(32) +

EncryptedPreMaster(blob) + ClientUserName(blob) + ClientMachineName(blob)

func EncodePlatformChallengeResponse

func EncodePlatformChallengeResponse(encryptedResponse, encryptedHWID, macData []byte) []byte

EncodePlatformChallengeResponse builds a CLIENT_PLATFORM_CHALLENGE_RESPONSE PDU (including preamble).

Layout: Preamble(4) + EncryptedChallengeResponse(blob) + EncryptedHWID(blob) + MACData(16)

func EncodePreamble

func EncodePreamble(msgType, flags byte, msgSize uint16) []byte

EncodePreamble serializes a 4-byte licensing preamble.

func IsValidClientError

func IsValidClientError(data []byte) bool

IsValidClientError checks if licensing data represents an ERROR_ALERT with STATUS_VALID_CLIENT — the common success case for TLS connections where the server indicates no license is needed.

Types

type Blob

type Blob struct {
	Type uint16
	Data []byte
}

Blob is a LICENSE_BINARY_BLOB (type(u16) + length(u16) + data).

func DecodeBlob

func DecodeBlob(data []byte) (Blob, []byte, error)

DecodeBlob parses a LICENSE_BINARY_BLOB from data. Returns the blob and remaining data.

type ErrorAlertData

type ErrorAlertData struct {
	ErrorCode       uint32
	StateTransition uint32
	ErrorInfo       Blob
}

ErrorAlertData holds parsed LICENSING_ERROR_MESSAGE fields.

func DecodeErrorAlert

func DecodeErrorAlert(data []byte) (*ErrorAlertData, error)

DecodeErrorAlert parses a LICENSING_ERROR_MESSAGE after the preamble.

Layout: dwErrorCode(u32) + dwStateTransition(u32) + bbErrorInfo(blob)

type LicenseCrypto

type LicenseCrypto struct {
	MACSaltKey          []byte // 16 bytes
	LicensingEncryptKey []byte // 16 bytes
}

LicenseCrypto holds derived licensing encryption keys and provides MAC computation and RC4 encryption per MS-RDPELE 5.1.3.

func DeriveLicenseKeys

func DeriveLicenseKeys(preMasterSecret, clientRandom, serverRandom []byte) *LicenseCrypto

DeriveLicenseKeys derives the licensing MAC salt key and encryption key from preMasterSecret, clientRandom, and serverRandom per MS-RDPELE 5.1.3.

MasterSecret = SaltedHash("A") + SaltedHash("BB") + SaltedHash("CCC")

where SaltedHash(I) = MD5(PM + SHA1(I + PM + CR + SR))

SessionKeyBlob = SaltedHash("A") + SaltedHash("BB") + SaltedHash("CCC")

where SaltedHash(I) = MD5(MS + SHA1(I + MS + SR + CR))  ← note reversed order

MACSaltKey = SessionKeyBlob[0:16] LicensingEncryptionKey = FinalHash(SessionKeyBlob[16:32])

where FinalHash(K) = MD5(K + CR + SR)

func (*LicenseCrypto) Decrypt

func (lc *LicenseCrypto) Decrypt(ciphertext []byte) []byte

Decrypt performs RC4 decryption with a fresh cipher per operation. RC4 is symmetric, so this is the same as Encrypt.

func (*LicenseCrypto) Encrypt

func (lc *LicenseCrypto) Encrypt(plaintext []byte) []byte

Encrypt performs RC4 encryption with a fresh cipher per operation.

func (*LicenseCrypto) MAC

func (lc *LicenseCrypto) MAC(data []byte) []byte

MAC computes the licensing MAC per MS-RDPELE 5.1.3:

SHAResult = SHA1(MACSaltKey + Pad1 + LE32(len(data)) + data)
MAC = MD5(MACSaltKey + Pad2 + SHAResult)

Returns 16-byte MAC.

type LicenseRequestData

type LicenseRequestData struct {
	ServerRandom    []byte // 32 bytes
	ProductInfo     ProductInfo
	KeyExchangeList Blob
	ServerCert      []byte // raw certificate bytes for sec.DecodeServerCertificate
	ScopeList       []Blob
}

LicenseRequestData holds parsed SERVER_LICENSE_REQUEST fields.

func DecodeLicenseRequest

func DecodeLicenseRequest(data []byte) (*LicenseRequestData, error)

DecodeLicenseRequest parses a SERVER_LICENSE_REQUEST after the preamble.

Layout: ServerRandom(32) + ProductInfo + KeyExchangeList(blob) +

ServerCertLen(u32) + ServerCert + ScopeCount(u32) + ScopeArray

type PlatformChallengeData

type PlatformChallengeData struct {
	ConnectFlags       uint32
	EncryptedChallenge Blob
	MACData            []byte // 16 bytes
}

PlatformChallengeData holds parsed SERVER_PLATFORM_CHALLENGE fields.

func DecodePlatformChallenge

func DecodePlatformChallenge(data []byte) (*PlatformChallengeData, error)

DecodePlatformChallenge parses a SERVER_PLATFORM_CHALLENGE after the preamble.

Layout: ConnectFlags(u32) + EncryptedPlatformChallenge(blob) + MACData(16)

type Preamble

type Preamble struct {
	MsgType byte
	Flags   byte
	MsgSize uint16
}

Preamble represents the 4-byte licensing preamble that precedes all licensing PDUs.

func DecodePreamble

func DecodePreamble(log *slog.Logger, data []byte) (Preamble, []byte, error)

DecodePreamble parses a 4-byte licensing preamble. Returns the preamble and the remaining data after it.

type ProductInfo

type ProductInfo struct {
	Version    uint32
	CompanyLen uint32
	Company    []byte
	ProductLen uint32
	Product    []byte
}

ProductInfo from SERVER_LICENSE_REQUEST (MS-RDPELE 2.2.2.1.1).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL