From feb5a95fc8d453547a0627f9b0ec76a6a6a2b306 Mon Sep 17 00:00:00 2001 From: Gaukas Wang Date: Sun, 10 Dec 2023 19:25:46 -0700 Subject: [PATCH] fix: no padding if raw clienthello is too short (#263) * Add a function `AlwaysPadToLen` to generate padding styles according to the raw clienthello. * Add an extra step in `FromRaw` after parsing the extension list to update the padding style. --- u_common.go | 9 +++++++++ u_tls_extensions.go | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/u_common.go b/u_common.go index bad01611..1757c895 100644 --- a/u_common.go +++ b/u_common.go @@ -545,6 +545,15 @@ func (chs *ClientHelloSpec) FromRaw(raw []byte, ctrlFlags ...bool) error { return err } + // if extension list includes padding, we update the padding-to-len according to + // the raw ClientHello length + for _, ext := range chs.Extensions { + if _, ok := ext.(*UtlsPaddingExtension); ok { + ext.(*UtlsPaddingExtension).GetPaddingLen = AlwaysPadToLen(len(raw) - 5) + break + } + } + return nil } diff --git a/u_tls_extensions.go b/u_tls_extensions.go index cf830607..d944f55b 100644 --- a/u_tls_extensions.go +++ b/u_tls_extensions.go @@ -1062,6 +1062,23 @@ func BoringPaddingStyle(unpaddedLen int) (int, bool) { return 0, false } +// AlwaysPadToLen could be used for parsed ClientHello, since some fingerprints +// might not use BoringSSL padding style and we want to pad to a the same length. +func AlwaysPadToLen(padToLen int) func(int) (int, bool) { + return func(unpaddedLen int) (int, bool) { + if unpaddedLen < padToLen { + paddingLen := padToLen - unpaddedLen + if paddingLen >= 4+1 { + paddingLen -= 4 + } else { + paddingLen = 1 + } + return paddingLen, true + } + return 0, false + } +} + // UtlsCompressCertExtension implements compress_certificate (27) and is only implemented client-side // for server certificates. Alternate certificate message formats // (https://datatracker.ietf.org/doc/html/rfc7250) are not supported.