From a64c29aa720105351bcc724739e0bebce40e3b00 Mon Sep 17 00:00:00 2001 From: decfox Date: Fri, 13 Jun 2025 15:01:58 +0530 Subject: [PATCH] chore: upgrade to v3.26.0 --- pkg/cmd/buildtool/desktop.go | 57 ++++++++++ pkg/experiment/echcheck/generate_test.go | 17 +++ pkg/experiment/echcheck/verbatim.go | 129 +++++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 pkg/cmd/buildtool/desktop.go create mode 100644 pkg/experiment/echcheck/generate_test.go create mode 100644 pkg/experiment/echcheck/verbatim.go diff --git a/pkg/cmd/buildtool/desktop.go b/pkg/cmd/buildtool/desktop.go new file mode 100644 index 00000000..1ef6b542 --- /dev/null +++ b/pkg/cmd/buildtool/desktop.go @@ -0,0 +1,57 @@ +package main + +import ( + "path/filepath" + "runtime" + + "github.com/apex/log" + "github.com/ooni/probe-engine/pkg/cmd/buildtool/internal/buildtoolmodel" + "github.com/ooni/probe-engine/pkg/shellx" + "github.com/spf13/cobra" +) + +// desktopSubcommand returns the desktop [cobra.Command]. +func desktopSubcommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "desktop", + Short: "Builds oonimkall and its dependencies for desktop", + } + + var targetOs string + + oomobileCmd := &cobra.Command{ + Use: "oomobile", + Short: "Builds oonimkall for desktop using oomobile", + Run: func(cmd *cobra.Command, args []string) { + desktopBuildOomobile(&buildDeps{}, targetOs) + }, + } + + oomobileCmd.Flags().StringVar(&targetOs, "target", "linux", "Target OS (e.g., linux, windows, darwin)") + + cmd.AddCommand(oomobileCmd) + return cmd +} + +// desktopBuildOomobile invokes the oomobile build. +func desktopBuildOomobile(deps buildtoolmodel.Dependencies, targetOs string) { + deps.GolangCheck() + + config := &gomobileConfig{ + deps: deps, + envp: &shellx.Envp{}, + extraFlags: []string{}, + output: filepath.Join("DESKTOP", "oonimkall.jar"), + target: "java", + } + config.envp.Append("GOOS", targetOs) + + // NOTE: we only support windows builds on amd64 for now + if targetOs == "windows" { + log.Infof("detected GOOS: %s, setting target as amd64", runtime.GOOS) + config.target = "java/amd64" + } + + log.Info("building the desktop jar using oomobile") + oomobileBuild(config) +} diff --git a/pkg/experiment/echcheck/generate_test.go b/pkg/experiment/echcheck/generate_test.go new file mode 100644 index 00000000..75f918b2 --- /dev/null +++ b/pkg/experiment/echcheck/generate_test.go @@ -0,0 +1,17 @@ +package echcheck + +import ( + "crypto/rand" + "testing" +) + +func TestParseableGREASEConfigList(t *testing.T) { + // A GREASE extension that can't be parsed is invalid. + grease, err := generateGreaseyECHConfigList(rand.Reader, "example.com") + if err != nil { + t.Fatal(err) + } + if _, err := parseECHConfigList(grease); err != nil { + t.Fatal(err) + } +} diff --git a/pkg/experiment/echcheck/verbatim.go b/pkg/experiment/echcheck/verbatim.go new file mode 100644 index 00000000..66fe96e0 --- /dev/null +++ b/pkg/experiment/echcheck/verbatim.go @@ -0,0 +1,129 @@ +// This file contains verbatim copies of the code from go's tls package at 1.23.4. +// https://github.com/golang/go/blob/go1.23.4/src/crypto/tls/common.go +// https://github.com/golang/go/blob/go1.23.4/src/crypto/tls/ech.go +// This should be refreshed to newer implementations if the ECH RFC change the format. + +// This file is: +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this code is governed by the BSD-style license found at: +// https://github.com/golang/go/blob/go1.23.4/LICENSE + +package echcheck + +import ( + "errors" + + "golang.org/x/crypto/cryptobyte" +) + +const extensionEncryptedClientHello uint16 = 0xfe0d + +type echCipher struct { + KDFID uint16 + AEADID uint16 +} + +type echExtension struct { + Type uint16 + Data []byte +} + +type echConfig struct { + raw []byte + + Version uint16 + Length uint16 + + ConfigID uint8 + KemID uint16 + PublicKey []byte + SymmetricCipherSuite []echCipher + + MaxNameLength uint8 + PublicName []byte + Extensions []echExtension +} + +var errMalformedECHConfig = errors.New("tls: malformed ECHConfigList") + +// parseECHConfigList parses a draft-ietf-tls-esni-18 ECHConfigList, returning a +// slice of parsed ECHConfigs, in the same order they were parsed, or an error +// if the list is malformed. +func parseECHConfigList(data []byte) ([]echConfig, error) { + s := cryptobyte.String(data) + // Skip the length prefix + var length uint16 + if !s.ReadUint16(&length) { + return nil, errMalformedECHConfig + } + if length != uint16(len(data)-2) { + return nil, errMalformedECHConfig + } + var configs []echConfig + for len(s) > 0 { + var ec echConfig + ec.raw = []byte(s) + if !s.ReadUint16(&ec.Version) { + return nil, errMalformedECHConfig + } + if !s.ReadUint16(&ec.Length) { + return nil, errMalformedECHConfig + } + if len(ec.raw) < int(ec.Length)+4 { + return nil, errMalformedECHConfig + } + ec.raw = ec.raw[:ec.Length+4] + if ec.Version != extensionEncryptedClientHello { + s.Skip(int(ec.Length)) + continue + } + if !s.ReadUint8(&ec.ConfigID) { + return nil, errMalformedECHConfig + } + if !s.ReadUint16(&ec.KemID) { + return nil, errMalformedECHConfig + } + if !s.ReadUint16LengthPrefixed((*cryptobyte.String)(&ec.PublicKey)) { + return nil, errMalformedECHConfig + } + var cipherSuites cryptobyte.String + if !s.ReadUint16LengthPrefixed(&cipherSuites) { + return nil, errMalformedECHConfig + } + for !cipherSuites.Empty() { + var c echCipher + if !cipherSuites.ReadUint16(&c.KDFID) { + return nil, errMalformedECHConfig + } + if !cipherSuites.ReadUint16(&c.AEADID) { + return nil, errMalformedECHConfig + } + ec.SymmetricCipherSuite = append(ec.SymmetricCipherSuite, c) + } + if !s.ReadUint8(&ec.MaxNameLength) { + return nil, errMalformedECHConfig + } + var publicName cryptobyte.String + if !s.ReadUint8LengthPrefixed(&publicName) { + return nil, errMalformedECHConfig + } + ec.PublicName = publicName + var extensions cryptobyte.String + if !s.ReadUint16LengthPrefixed(&extensions) { + return nil, errMalformedECHConfig + } + for !extensions.Empty() { + var e echExtension + if !extensions.ReadUint16(&e.Type) { + return nil, errMalformedECHConfig + } + if !extensions.ReadUint16LengthPrefixed((*cryptobyte.String)(&e.Data)) { + return nil, errMalformedECHConfig + } + ec.Extensions = append(ec.Extensions, e) + } + + configs = append(configs, ec) + } + return configs, nil +}