Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions pkg/cmd/buildtool/desktop.go
Original file line number Diff line number Diff line change
@@ -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)

Check failure on line 56 in pkg/cmd/buildtool/desktop.go

View workflow job for this annotation

GitHub Actions / test

undefined: oomobileBuild
}
17 changes: 17 additions & 0 deletions pkg/experiment/echcheck/generate_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
129 changes: 129 additions & 0 deletions pkg/experiment/echcheck/verbatim.go
Original file line number Diff line number Diff line change
@@ -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 {

Check failure on line 26 in pkg/experiment/echcheck/verbatim.go

View workflow job for this annotation

GitHub Actions / test

echExtension redeclared in this block
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) {

Check failure on line 117 in pkg/experiment/echcheck/verbatim.go

View workflow job for this annotation

GitHub Actions / test

e.Type undefined (type echExtension has no field or method Type)
return nil, errMalformedECHConfig
}
if !extensions.ReadUint16LengthPrefixed((*cryptobyte.String)(&e.Data)) {

Check failure on line 120 in pkg/experiment/echcheck/verbatim.go

View workflow job for this annotation

GitHub Actions / test

e.Data undefined (type echExtension has no field or method Data)
return nil, errMalformedECHConfig
}
ec.Extensions = append(ec.Extensions, e)
}

configs = append(configs, ec)
}
return configs, nil
}
Loading