UnmarshalBinary decodes the data back into an ECH config. Borrowed from github.com/OmarTariq612/goech with modifications. Original code: Copyright (c) 2023 Omar Tariq AbdEl-Raziq
(data []byte)
| 966 | // Borrowed from github.com/OmarTariq612/goech with modifications. |
| 967 | // Original code: Copyright (c) 2023 Omar Tariq AbdEl-Raziq |
| 968 | func (echCfg *echConfig) UnmarshalBinary(data []byte) error { |
| 969 | var content cryptobyte.String |
| 970 | b := cryptobyte.String(data) |
| 971 | |
| 972 | if !b.ReadUint16(&echCfg.Version) { |
| 973 | return errInvalidLen |
| 974 | } |
| 975 | if echCfg.Version != draftTLSESNI25 { |
| 976 | return fmt.Errorf("supported version must be %d: got %d", draftTLSESNI25, echCfg.Version) |
| 977 | } |
| 978 | |
| 979 | if !b.ReadUint16LengthPrefixed(&content) || !b.Empty() { |
| 980 | return errInvalidLen |
| 981 | } |
| 982 | |
| 983 | var t cryptobyte.String |
| 984 | var pk []byte |
| 985 | |
| 986 | if !content.ReadUint8(&echCfg.ConfigID) || |
| 987 | !content.ReadUint16((*uint16)(&echCfg.KEMID)) || |
| 988 | !content.ReadUint16LengthPrefixed(&t) || |
| 989 | !t.ReadBytes(&pk, len(t)) || |
| 990 | !content.ReadUint16LengthPrefixed(&t) || |
| 991 | len(t)%4 != 0 /* the length of (KDFs and AEADs) must be divisible by 4 */ { |
| 992 | return errInvalidLen |
| 993 | } |
| 994 | |
| 995 | if !echCfg.KEMID.IsValid() { |
| 996 | return fmt.Errorf("invalid KEM ID: %d", echCfg.KEMID) |
| 997 | } |
| 998 | |
| 999 | var err error |
| 1000 | if echCfg.PublicKey, err = echCfg.KEMID.Scheme().UnmarshalBinaryPublicKey(pk); err != nil { |
| 1001 | return fmt.Errorf("parsing public_key: %w", err) |
| 1002 | } |
| 1003 | |
| 1004 | echCfg.CipherSuites = echCfg.CipherSuites[:0] |
| 1005 | |
| 1006 | for !t.Empty() { |
| 1007 | var hpkeKDF, hpkeAEAD uint16 |
| 1008 | if !t.ReadUint16(&hpkeKDF) || !t.ReadUint16(&hpkeAEAD) { |
| 1009 | // we have already checked that the length is divisible by 4 |
| 1010 | panic("this must not happen") |
| 1011 | } |
| 1012 | if !hpke.KDF(hpkeKDF).IsValid() { |
| 1013 | return fmt.Errorf("invalid KDF ID: %d", hpkeKDF) |
| 1014 | } |
| 1015 | if !hpke.AEAD(hpkeAEAD).IsValid() { |
| 1016 | return fmt.Errorf("invalid AEAD ID: %d", hpkeAEAD) |
| 1017 | } |
| 1018 | echCfg.CipherSuites = append(echCfg.CipherSuites, hpkeSymmetricCipherSuite{ |
| 1019 | KDFID: hpke.KDF(hpkeKDF), |
| 1020 | AEADID: hpke.AEAD(hpkeAEAD), |
| 1021 | }) |
| 1022 | } |
| 1023 | |
| 1024 | var rawPublicName []byte |
| 1025 | if !content.ReadUint8(&echCfg.MaxNameLength) || |
no test coverage detected