mirror of
https://github.com/XTLS/REALITY.git
synced 2025-08-22 22:48:36 +00:00
crypto/tls: improve ech parsing errors
Make the errors we return when parsing an ECHConfig slightly more verbose. Fixes #71706 Change-Id: Id138fd9defec71ce492a490a71af4981cb9ede51 Reviewed-on: https://go-review.googlesource.com/c/go/+/650720 Auto-Submit: Roland Shoemaker <roland@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
6244b56531
commit
82d61a9469
45
ech.go
45
ech.go
@ -54,19 +54,30 @@ type echConfig struct {
|
|||||||
Extensions []echExtension
|
Extensions []echExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
var errMalformedECHConfig = errors.New("tls: malformed ECHConfigList")
|
var errMalformedECHConfigList = errors.New("tls: malformed ECHConfigList")
|
||||||
|
|
||||||
|
type echConfigErr struct {
|
||||||
|
field string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *echConfigErr) Error() string {
|
||||||
|
if e.field == "" {
|
||||||
|
return "tls: malformed ECHConfig"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("tls: malformed ECHConfig, invalid %s field", e.field)
|
||||||
|
}
|
||||||
|
|
||||||
func parseECHConfig(enc []byte) (skip bool, ec echConfig, err error) {
|
func parseECHConfig(enc []byte) (skip bool, ec echConfig, err error) {
|
||||||
s := cryptobyte.String(enc)
|
s := cryptobyte.String(enc)
|
||||||
ec.raw = []byte(enc)
|
ec.raw = []byte(enc)
|
||||||
if !s.ReadUint16(&ec.Version) {
|
if !s.ReadUint16(&ec.Version) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"version"}
|
||||||
}
|
}
|
||||||
if !s.ReadUint16(&ec.Length) {
|
if !s.ReadUint16(&ec.Length) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"length"}
|
||||||
}
|
}
|
||||||
if len(ec.raw) < int(ec.Length)+4 {
|
if len(ec.raw) < int(ec.Length)+4 {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"length"}
|
||||||
}
|
}
|
||||||
ec.raw = ec.raw[:ec.Length+4]
|
ec.raw = ec.raw[:ec.Length+4]
|
||||||
if ec.Version != extensionEncryptedClientHello {
|
if ec.Version != extensionEncryptedClientHello {
|
||||||
@ -74,47 +85,47 @@ func parseECHConfig(enc []byte) (skip bool, ec echConfig, err error) {
|
|||||||
return true, echConfig{}, nil
|
return true, echConfig{}, nil
|
||||||
}
|
}
|
||||||
if !s.ReadUint8(&ec.ConfigID) {
|
if !s.ReadUint8(&ec.ConfigID) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"config_id"}
|
||||||
}
|
}
|
||||||
if !s.ReadUint16(&ec.KemID) {
|
if !s.ReadUint16(&ec.KemID) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"kem_id"}
|
||||||
}
|
}
|
||||||
if !readUint16LengthPrefixed(&s, &ec.PublicKey) {
|
if !readUint16LengthPrefixed(&s, &ec.PublicKey) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"public_key"}
|
||||||
}
|
}
|
||||||
var cipherSuites cryptobyte.String
|
var cipherSuites cryptobyte.String
|
||||||
if !s.ReadUint16LengthPrefixed(&cipherSuites) {
|
if !s.ReadUint16LengthPrefixed(&cipherSuites) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"cipher_suites"}
|
||||||
}
|
}
|
||||||
for !cipherSuites.Empty() {
|
for !cipherSuites.Empty() {
|
||||||
var c echCipher
|
var c echCipher
|
||||||
if !cipherSuites.ReadUint16(&c.KDFID) {
|
if !cipherSuites.ReadUint16(&c.KDFID) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"cipher_suites kdf_id"}
|
||||||
}
|
}
|
||||||
if !cipherSuites.ReadUint16(&c.AEADID) {
|
if !cipherSuites.ReadUint16(&c.AEADID) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"cipher_suites aead_id"}
|
||||||
}
|
}
|
||||||
ec.SymmetricCipherSuite = append(ec.SymmetricCipherSuite, c)
|
ec.SymmetricCipherSuite = append(ec.SymmetricCipherSuite, c)
|
||||||
}
|
}
|
||||||
if !s.ReadUint8(&ec.MaxNameLength) {
|
if !s.ReadUint8(&ec.MaxNameLength) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"maximum_name_length"}
|
||||||
}
|
}
|
||||||
var publicName cryptobyte.String
|
var publicName cryptobyte.String
|
||||||
if !s.ReadUint8LengthPrefixed(&publicName) {
|
if !s.ReadUint8LengthPrefixed(&publicName) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"public_name"}
|
||||||
}
|
}
|
||||||
ec.PublicName = publicName
|
ec.PublicName = publicName
|
||||||
var extensions cryptobyte.String
|
var extensions cryptobyte.String
|
||||||
if !s.ReadUint16LengthPrefixed(&extensions) {
|
if !s.ReadUint16LengthPrefixed(&extensions) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"extensions"}
|
||||||
}
|
}
|
||||||
for !extensions.Empty() {
|
for !extensions.Empty() {
|
||||||
var e echExtension
|
var e echExtension
|
||||||
if !extensions.ReadUint16(&e.Type) {
|
if !extensions.ReadUint16(&e.Type) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"extensions type"}
|
||||||
}
|
}
|
||||||
if !extensions.ReadUint16LengthPrefixed((*cryptobyte.String)(&e.Data)) {
|
if !extensions.ReadUint16LengthPrefixed((*cryptobyte.String)(&e.Data)) {
|
||||||
return false, echConfig{}, errMalformedECHConfig
|
return false, echConfig{}, &echConfigErr{"extensions data"}
|
||||||
}
|
}
|
||||||
ec.Extensions = append(ec.Extensions, e)
|
ec.Extensions = append(ec.Extensions, e)
|
||||||
}
|
}
|
||||||
@ -129,10 +140,10 @@ func parseECHConfigList(data []byte) ([]echConfig, error) {
|
|||||||
s := cryptobyte.String(data)
|
s := cryptobyte.String(data)
|
||||||
var length uint16
|
var length uint16
|
||||||
if !s.ReadUint16(&length) {
|
if !s.ReadUint16(&length) {
|
||||||
return nil, errMalformedECHConfig
|
return nil, errMalformedECHConfigList
|
||||||
}
|
}
|
||||||
if length != uint16(len(data)-2) {
|
if length != uint16(len(data)-2) {
|
||||||
return nil, errMalformedECHConfig
|
return nil, errMalformedECHConfigList
|
||||||
}
|
}
|
||||||
var configs []echConfig
|
var configs []echConfig
|
||||||
for len(s) > 0 {
|
for len(s) > 0 {
|
||||||
|
Loading…
Reference in New Issue
Block a user