tls_client_hello: Go parsing library

KS implementation details

License: MIT

References

This page hosts a formal specification of tls_client_hello using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Go source code to parse tls_client_hello

tls_client_hello.go

// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.

import (
	"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
	"bytes"
)

type TlsClientHello struct {
	Version *TlsClientHello_Version
	Random *TlsClientHello_Random
	SessionId *TlsClientHello_SessionId
	CipherSuites *TlsClientHello_CipherSuites
	CompressionMethods *TlsClientHello_CompressionMethods
	Extensions *TlsClientHello_Extensions
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent interface{}
}
func NewTlsClientHello() *TlsClientHello {
	return &TlsClientHello{
	}
}

func (this *TlsClientHello) Read(io *kaitai.Stream, parent interface{}, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp1 := NewTlsClientHello_Version()
	err = tmp1.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Version = tmp1
	tmp2 := NewTlsClientHello_Random()
	err = tmp2.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Random = tmp2
	tmp3 := NewTlsClientHello_SessionId()
	err = tmp3.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.SessionId = tmp3
	tmp4 := NewTlsClientHello_CipherSuites()
	err = tmp4.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.CipherSuites = tmp4
	tmp5 := NewTlsClientHello_CompressionMethods()
	err = tmp5.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.CompressionMethods = tmp5
	tmp6, err := this._io.EOF()
	if err != nil {
		return err
	}
	if (tmp6 == false) {
		tmp7 := NewTlsClientHello_Extensions()
		err = tmp7.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Extensions = tmp7
	}
	return err
}
type TlsClientHello_ServerName struct {
	NameType uint8
	Length uint16
	HostName []byte
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello_Sni
}
func NewTlsClientHello_ServerName() *TlsClientHello_ServerName {
	return &TlsClientHello_ServerName{
	}
}

func (this *TlsClientHello_ServerName) Read(io *kaitai.Stream, parent *TlsClientHello_Sni, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp8, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.NameType = tmp8
	tmp9, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Length = uint16(tmp9)
	tmp10, err := this._io.ReadBytes(int(this.Length))
	if err != nil {
		return err
	}
	tmp10 = tmp10
	this.HostName = tmp10
	return err
}
type TlsClientHello_Random struct {
	GmtUnixTime uint32
	Random []byte
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello
}
func NewTlsClientHello_Random() *TlsClientHello_Random {
	return &TlsClientHello_Random{
	}
}

func (this *TlsClientHello_Random) Read(io *kaitai.Stream, parent *TlsClientHello, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp11, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.GmtUnixTime = uint32(tmp11)
	tmp12, err := this._io.ReadBytes(int(28))
	if err != nil {
		return err
	}
	tmp12 = tmp12
	this.Random = tmp12
	return err
}
type TlsClientHello_SessionId struct {
	Len uint8
	Sid []byte
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello
}
func NewTlsClientHello_SessionId() *TlsClientHello_SessionId {
	return &TlsClientHello_SessionId{
	}
}

func (this *TlsClientHello_SessionId) Read(io *kaitai.Stream, parent *TlsClientHello, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp13, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Len = tmp13
	tmp14, err := this._io.ReadBytes(int(this.Len))
	if err != nil {
		return err
	}
	tmp14 = tmp14
	this.Sid = tmp14
	return err
}
type TlsClientHello_Sni struct {
	ListLength uint16
	ServerNames []*TlsClientHello_ServerName
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello_Extension
}
func NewTlsClientHello_Sni() *TlsClientHello_Sni {
	return &TlsClientHello_Sni{
	}
}

func (this *TlsClientHello_Sni) Read(io *kaitai.Stream, parent *TlsClientHello_Extension, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp15, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.ListLength = uint16(tmp15)
	for i := 1;; i++ {
		tmp16, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp16 {
			break
		}
		tmp17 := NewTlsClientHello_ServerName()
		err = tmp17.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.ServerNames = append(this.ServerNames, tmp17)
	}
	return err
}
type TlsClientHello_CipherSuites struct {
	Len uint16
	CipherSuites []uint16
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello
}
func NewTlsClientHello_CipherSuites() *TlsClientHello_CipherSuites {
	return &TlsClientHello_CipherSuites{
	}
}

func (this *TlsClientHello_CipherSuites) Read(io *kaitai.Stream, parent *TlsClientHello, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp18, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Len = uint16(tmp18)
	for i := 0; i < int((this.Len / 2)); i++ {
		_ = i
		tmp19, err := this._io.ReadU2be()
		if err != nil {
			return err
		}
		this.CipherSuites = append(this.CipherSuites, tmp19)
	}
	return err
}
type TlsClientHello_CompressionMethods struct {
	Len uint8
	CompressionMethods []byte
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello
}
func NewTlsClientHello_CompressionMethods() *TlsClientHello_CompressionMethods {
	return &TlsClientHello_CompressionMethods{
	}
}

func (this *TlsClientHello_CompressionMethods) Read(io *kaitai.Stream, parent *TlsClientHello, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp20, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Len = tmp20
	tmp21, err := this._io.ReadBytes(int(this.Len))
	if err != nil {
		return err
	}
	tmp21 = tmp21
	this.CompressionMethods = tmp21
	return err
}
type TlsClientHello_Alpn struct {
	ExtLen uint16
	AlpnProtocols []*TlsClientHello_Protocol
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello_Extension
}
func NewTlsClientHello_Alpn() *TlsClientHello_Alpn {
	return &TlsClientHello_Alpn{
	}
}

func (this *TlsClientHello_Alpn) Read(io *kaitai.Stream, parent *TlsClientHello_Extension, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp22, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.ExtLen = uint16(tmp22)
	for i := 1;; i++ {
		tmp23, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp23 {
			break
		}
		tmp24 := NewTlsClientHello_Protocol()
		err = tmp24.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.AlpnProtocols = append(this.AlpnProtocols, tmp24)
	}
	return err
}
type TlsClientHello_Extensions struct {
	Len uint16
	Extensions []*TlsClientHello_Extension
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello
}
func NewTlsClientHello_Extensions() *TlsClientHello_Extensions {
	return &TlsClientHello_Extensions{
	}
}

func (this *TlsClientHello_Extensions) Read(io *kaitai.Stream, parent *TlsClientHello, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp25, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Len = uint16(tmp25)
	for i := 1;; i++ {
		tmp26, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp26 {
			break
		}
		tmp27 := NewTlsClientHello_Extension()
		err = tmp27.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Extensions = append(this.Extensions, tmp27)
	}
	return err
}
type TlsClientHello_Version struct {
	Major uint8
	Minor uint8
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello
}
func NewTlsClientHello_Version() *TlsClientHello_Version {
	return &TlsClientHello_Version{
	}
}

func (this *TlsClientHello_Version) Read(io *kaitai.Stream, parent *TlsClientHello, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp28, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Major = tmp28
	tmp29, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Minor = tmp29
	return err
}
type TlsClientHello_Protocol struct {
	Strlen uint8
	Name []byte
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello_Alpn
}
func NewTlsClientHello_Protocol() *TlsClientHello_Protocol {
	return &TlsClientHello_Protocol{
	}
}

func (this *TlsClientHello_Protocol) Read(io *kaitai.Stream, parent *TlsClientHello_Alpn, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp30, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Strlen = tmp30
	tmp31, err := this._io.ReadBytes(int(this.Strlen))
	if err != nil {
		return err
	}
	tmp31 = tmp31
	this.Name = tmp31
	return err
}
type TlsClientHello_Extension struct {
	Type uint16
	Len uint16
	Body interface{}
	_io *kaitai.Stream
	_root *TlsClientHello
	_parent *TlsClientHello_Extensions
	_raw_Body []byte
}
func NewTlsClientHello_Extension() *TlsClientHello_Extension {
	return &TlsClientHello_Extension{
	}
}

func (this *TlsClientHello_Extension) Read(io *kaitai.Stream, parent *TlsClientHello_Extensions, root *TlsClientHello) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp32, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Type = uint16(tmp32)
	tmp33, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Len = uint16(tmp33)
	switch (this.Type) {
	case 0:
		tmp34, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp34 = tmp34
		this._raw_Body = tmp34
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp35 := NewTlsClientHello_Sni()
		err = tmp35.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp35
	case 16:
		tmp36, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp36 = tmp36
		this._raw_Body = tmp36
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp37 := NewTlsClientHello_Alpn()
		err = tmp37.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp37
	default:
		tmp38, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp38 = tmp38
		this._raw_Body = tmp38
	}
	return err
}