goech

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2025 License: MIT Imports: 9 Imported by: 20

README

Go Reference

goech

Encrypted Client Hello (ECH) is an extension to the TLS version 1.3, it prevents leaking the Server Name Indication (SNI) (and other fields in the ClientHello message).

This is done using public key cryptography, by either having the client preconfigured with an ECH Configuration, or fetching that configuration by making a DNS lookup using a special HTTPS record.

This library helps with parsing and generating those ECH configurations.

Examples

go get -u github.com/OmarTariq612/goech
package main

import (
	"fmt"

	"github.com/OmarTariq612/goech"
)

func main() {
	echConfigList, err := goech.ECHConfigListFromBase64("AEX+DQBBrAAgACCInfIgdvp+4xqPkMYvPt1Rv7zxtllWm3SjIjWxBoEgfAAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA=")
	if err != nil {
		panic(err)
	}

	fmt.Println(string(echConfigList[0].RawPublicName)) // cloudflare-ech.com
	pk, _ := echConfigList[0].PublicKey.MarshalBinary()
	fmt.Printf("%x\n", pk)                              // 889df22076fa7ee31a8f90c62f3edd51bfbcf1b659569b74a32235b10681207c
	fmt.Println(goech.KemMapping[echConfigList[0].KEM]) // X25519-SHA256
}
package main

import (
	"fmt"

	"github.com/OmarTariq612/goech"
	"github.com/cloudflare/circl/hpke"
)

func main() {
	echKeySet, err := goech.GenerateECHKeySet(5, "example.com", hpke.KEM_X25519_HKDF_SHA256)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(echKeySet.ECHConfig.RawPublicName)) // example.com
	pk, _ := echKeySet.ECHConfig.PublicKey.MarshalBinary()
	fmt.Printf("%x\n", pk)                                 // 0b7288f2cd9c0f4063ab2a9478407136f448f7ffe4a6410fee855fdf4f3ed811
	fmt.Println(goech.KemMapping[echKeySet.ECHConfig.KEM]) // X25519-SHA256
}

REF

License

goech is available under the MIT license.

Documentation

Index

Constants

View Source
const (
	DraftTLSESNI16 = 0xfe0d
)

Variables

View Source
var (
	KDFMapping = [...]string{
		hpke.KDF_HKDF_SHA256: "SHA256",
		hpke.KDF_HKDF_SHA384: "SHA384",
		hpke.KDF_HKDF_SHA512: "SHA512",
	}

	AEADMapping = [...]string{
		hpke.AEAD_AES128GCM:        "AES128GCM",
		hpke.AEAD_AES256GCM:        "AES256GCM",
		hpke.AEAD_ChaCha20Poly1305: "CHACHA20POLY1305",
	}

	KemMapping = [...]string{
		hpke.KEM_P256_HKDF_SHA256:   "P256-SHA256",
		hpke.KEM_P384_HKDF_SHA384:   "P384-SHA384",
		hpke.KEM_P521_HKDF_SHA512:   "P521-SHA512",
		hpke.KEM_X25519_HKDF_SHA256: "X25519-SHA256",
		hpke.KEM_X448_HKDF_SHA512:   "X25519-SHA512",
	}
)
View Source
var (
	ErrNotSupportedVersion = fmt.Errorf("goech: %d is the only supported version", DraftTLSESNI16)
	ErrInvalidLen          = errors.New("goech: invalid length")
)

Functions

func GenerateKeyPair

func GenerateKeyPair(kem hpke.KEM) (kem.PublicKey, kem.PrivateKey, error)

func MarshalECHConfigArgs

func MarshalECHConfigArgs(configs ...ECHConfig) ([]byte, error)

func MarshalECHConfigList

func MarshalECHConfigList(configs []ECHConfig) ([]byte, error)

func MarshalECHKeySetArgs

func MarshalECHKeySetArgs(keysets ...ECHKeySet) ([]byte, error)

func MarshalECHKeySetList

func MarshalECHKeySetList(keysets []ECHKeySet) ([]byte, error)

Types

type ECHConfig

type ECHConfig struct {
	// The version of the ECHConfig struct.
	Version uint16

	// A one-byte identifier for the given HPKE key configuration.
	// This is used by clients to indicate the key used for ClientHello encryption.
	//
	// Section 4.1 describes how client-facing servers allocate this value.
	ConfigID uint8

	// The HPKE KEM identifier corresponding to public_key.
	// Clients MUST ignore any ECHConfig structure with a key using a KEM they do not support
	KEM hpke.KEM

	// The HPKE public key used by the client to encrypt ClientHelloInner.
	PublicKey kem.PublicKey

	// The list of HPKE KDF and AEAD identifier pairs clients can use for encrypting ClientHelloInner.
	//
	// See Section 6.1 for how clients choose from this list.
	CipherSuites []HpkeSymmetricCipherSuite

	// The longest name of a backend server, if known. If not known, this value can be set to zero.
	//
	// It is used to compute padding (Section 6.1.3) and does not constrain server name lengths.
	// Names may exceed this length if, e.g., the server uses wildcard names or added new names to the anonymity set.
	MaxNameLength uint8

	// The DNS name of the client-facing server, i.e., the entity trusted to update the ECH configuration.
	//
	// This is used to correct misconfigured clients, as described in Section 6.1.6.
	RawPublicName []byte

	// A list of ECHConfigExtension values that the client must take into consideration when generating a ClientHello message.
	//
	// Each ECHConfigExtension has a 2-octet type and opaque data value,
	// where the data value is encoded with a 2-octet integer representing the length of the data, in network byte order.
	RawExtensions []byte
}

ECHConfig represents an Encrypted Client Hello configuration.

Encoding is done according to the ECHConfig struct defined in the draft-ietf-tls-esni-22. It also matches `tls.Config.EncryptedClientHelloKeys.Config` in the Go standard library.

func (ECHConfig) AppendBinary

func (ech ECHConfig) AppendBinary(b []byte) ([]byte, error)

func (*ECHConfig) Equal

func (ech *ECHConfig) Equal(other *ECHConfig) bool

func (*ECHConfig) FromBase64

func (ech *ECHConfig) FromBase64(echConfigBase64 string) error

func (ECHConfig) MarshalBinary

func (ech ECHConfig) MarshalBinary() ([]byte, error)

func (ECHConfig) String

func (ech ECHConfig) String() string

func (ECHConfig) ToBase64

func (ech ECHConfig) ToBase64() (string, error)

func (ECHConfig) ToBase64OrPanic

func (ech ECHConfig) ToBase64OrPanic() string

func (*ECHConfig) UnmarshalBinary

func (ech *ECHConfig) UnmarshalBinary(data []byte) error

type ECHConfigList

type ECHConfigList []ECHConfig

The ECHConfigList structure contains one or more ECHConfig structures in decreasing order of preference. This allows a server to support multiple versions of ECH and multiple sets of ECH parameters.

Encoding is done according to the ECHConfigList type defined in the draft-ietf-tls-esni-22. It also matches `tls.Config.EncryptedClientHelloConfigList` in the Go standard library.

func ECHConfigListFromBase64

func ECHConfigListFromBase64(echConfigListBase64 string) (ECHConfigList, error)

func UnmarshalECHConfigList

func UnmarshalECHConfigList(data []byte) (configList ECHConfigList, err error)

func (ECHConfigList) AppendBinary

func (configs ECHConfigList) AppendBinary(b []byte) ([]byte, error)

func (ECHConfigList) Equal

func (configs ECHConfigList) Equal(other ECHConfigList) bool

func (*ECHConfigList) FromBase64

func (configs *ECHConfigList) FromBase64(echConfigListBase64 string) error

func (ECHConfigList) MarshalBinary

func (configs ECHConfigList) MarshalBinary() ([]byte, error)

func (ECHConfigList) ToBase64

func (configs ECHConfigList) ToBase64() (string, error)

func (ECHConfigList) ToBase64OrPanic

func (configs ECHConfigList) ToBase64OrPanic() string

func (*ECHConfigList) UnmarshalBinary

func (configs *ECHConfigList) UnmarshalBinary(data []byte) error

type ECHKeySet

type ECHKeySet struct {
	PrivateKey kem.PrivateKey
	ECHConfig  ECHConfig
}

ECHKeySet represents an ECHConfig and its corresponding private key.

Encoding of the ECHKeySet has the format defined below (in TLS syntax). NOTE: The ECH standard does not specify this format.

struct {
	opaque PrivateKey<0..2^16-1>;
	ECHConfig config<0..2^16-1>;
} ECHKeySet;

This encoding is written specfically to match `tls.EXP_UnmarshalECHKeys` encoding of cfgo (the cloudflare fork of go). This is subject to change in the future.

func GenerateECHKeySet

func GenerateECHKeySet(configID uint8, domain string, kem hpke.KEM, cipherSuites []HpkeSymmetricCipherSuite) (ECHKeySet, error)

func (ECHKeySet) AppendBinary

func (key ECHKeySet) AppendBinary(b []byte) ([]byte, error)

func (*ECHKeySet) Equal

func (key *ECHKeySet) Equal(other *ECHKeySet) bool

func (*ECHKeySet) FromBase64

func (key *ECHKeySet) FromBase64(keySetBase64 string) error

func (ECHKeySet) MarshalBinary

func (key ECHKeySet) MarshalBinary() ([]byte, error)

len - privatekey - len - config

func (ECHKeySet) String

func (key ECHKeySet) String() string

func (*ECHKeySet) ToBase64

func (key *ECHKeySet) ToBase64() (string, error)

func (*ECHKeySet) ToBase64OrPanic

func (key *ECHKeySet) ToBase64OrPanic() string

func (*ECHKeySet) UnmarshalBinary

func (key *ECHKeySet) UnmarshalBinary(data []byte) error

type ECHKeySetList

type ECHKeySetList []ECHKeySet

ECHKeySetList is a sequence of ECHKeySet.

NOTE: The ECH standard does not specify the encoding of this type This encoding is written specfically to match `tls.EXP_UnmarshalECHKeys` encoding of cfgo (the cloudflare fork of go). This is subject to change in the future.

func ECHKeySetListFromBase64

func ECHKeySetListFromBase64(echKeySetListBase64 string) (ECHKeySetList, error)

func UnmarshalECHKeySetList

func UnmarshalECHKeySetList(data []byte) (ECHKeySetList, error)

func (ECHKeySetList) AppendBinary

func (keysets ECHKeySetList) AppendBinary(b []byte) ([]byte, error)

func (ECHKeySetList) Equal

func (keysets ECHKeySetList) Equal(other ECHKeySetList) bool

func (*ECHKeySetList) FromBase64

func (keysets *ECHKeySetList) FromBase64(keySetListBase64 string) error

func (ECHKeySetList) MarshalBinary

func (keysets ECHKeySetList) MarshalBinary() ([]byte, error)

func (ECHKeySetList) ToBase64

func (keysets ECHKeySetList) ToBase64() (string, error)

func (ECHKeySetList) ToBase64OrPanic

func (keysets ECHKeySetList) ToBase64OrPanic() string

func (*ECHKeySetList) UnmarshalBinary

func (keysets *ECHKeySetList) UnmarshalBinary(data []byte) error

type HpkeSymmetricCipherSuite

type HpkeSymmetricCipherSuite struct {
	KDF  hpke.KDF
	AEAD hpke.AEAD
}

func (HpkeSymmetricCipherSuite) String

func (cipherSuite HpkeSymmetricCipherSuite) String() string

type InvalidAEADError

type InvalidAEADError uint16

func (InvalidAEADError) Error

func (aead InvalidAEADError) Error() string

type InvalidKDFError

type InvalidKDFError uint16

func (InvalidKDFError) Error

func (kdf InvalidKDFError) Error() string

type InvalidKEMError

type InvalidKEMError uint16

func (InvalidKEMError) Error

func (kem InvalidKEMError) Error() string

type InvalidPublicNameLenError

type InvalidPublicNameLenError uint

func (InvalidPublicNameLenError) Error

func (length InvalidPublicNameLenError) Error() string

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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