refactor: merge tlsx into netxlite (#403)

Part of https://github.com/ooni/probe/issues/1505
This commit is contained in:
Simone Basso
2021-06-25 12:39:45 +02:00
committed by GitHub
parent f1ee763f94
commit 7f2463d745
15 changed files with 41 additions and 47 deletions
@@ -12,7 +12,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
const (
@@ -183,7 +183,7 @@ func (m Measurer) Run(ctx context.Context, sess model.ExperimentSession,
measurement.TestKeys = testkeys
urlgetter.RegisterExtensions(measurement)
certPool := tlsx.NewDefaultCertPool()
certPool := netxlite.NewDefaultCertPool()
// used multiple times below
multi := urlgetter.Multi{
+2 -2
View File
@@ -10,7 +10,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
const (
@@ -111,7 +111,7 @@ func (m Measurer) Run(ctx context.Context, sess model.ExperimentSession,
defer cancel()
urlgetter.RegisterExtensions(measurement)
certPool := tlsx.NewDefaultCertPool()
certPool := netxlite.NewDefaultCertPool()
signalCABytes := []byte(signalCA)
if m.Config.SignalCA != "" {
signalCABytes = []byte(m.Config.SignalCA)
@@ -10,8 +10,8 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// The Configurer job is to construct a Configuration that can
@@ -90,7 +90,7 @@ func (c Configurer) NewConfiguration() (Configuration, error) {
if c.Config.TLSServerName != "" {
configuration.HTTPConfig.TLSConfig.ServerName = c.Config.TLSServerName
}
err = tlsx.ConfigureTLSVersion(
err = netxlite.ConfigureTLSVersion(
configuration.HTTPConfig.TLSConfig, c.Config.TLSVersion,
)
if err != nil {
@@ -10,8 +10,8 @@ import (
"github.com/apex/log"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
func TestConfigurerNewConfigurationVanilla(t *testing.T) {
@@ -711,7 +711,7 @@ func TestConfigurerNewConfigurationTLSvInvalid(t *testing.T) {
Saver: saver,
}
_, err := configurer.NewConfiguration()
if !errors.Is(err, tlsx.ErrInvalidTLSVersion) {
if !errors.Is(err, netxlite.ErrInvalidTLSVersion) {
t.Fatalf("not the error we expected: %+v", err)
}
}
@@ -9,7 +9,7 @@ import (
"strings"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// Logger is the interface we expect from a logger
@@ -66,7 +66,7 @@ func (h *Handler) OnMeasurement(m modelx.Measurement) {
h.logger.Debugf(
"TLS done: %s, %s (alpn='%s')",
fmtError(m.TLSHandshakeDone.Error),
tlsx.VersionString(m.TLSHandshakeDone.ConnectionState.Version),
netxlite.TLSVersionString(m.TLSHandshakeDone.ConnectionState.Version),
m.TLSHandshakeDone.ConnectionState.NegotiatedProtocol,
)
}
@@ -20,7 +20,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/legacy/oonitemplates"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// ExtSpec describes a data format extension
@@ -463,12 +463,12 @@ func NewTLSHandshakesList(results oonitemplates.Results) TLSHandshakesList {
var out TLSHandshakesList
for _, in := range results.TLSHandshakes {
out = append(out, TLSHandshake{
CipherSuite: tlsx.CipherSuiteString(in.ConnectionState.CipherSuite),
CipherSuite: netxlite.TLSCipherSuiteString(in.ConnectionState.CipherSuite),
Failure: makeFailure(in.Error),
NegotiatedProtocol: in.ConnectionState.NegotiatedProtocol,
PeerCertificates: makePeerCerts(in.ConnectionState.PeerCertificates),
T: in.DurationSinceBeginning.Seconds(),
TLSVersion: tlsx.VersionString(in.ConnectionState.Version),
TLSVersion: netxlite.TLSVersionString(in.ConnectionState.Version),
})
}
return out
+2 -3
View File
@@ -37,7 +37,6 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/netx/quicdialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsdialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -110,7 +109,7 @@ type tlsHandshaker interface {
net.Conn, tls.ConnectionState, error)
}
var defaultCertPool *x509.CertPool = tlsx.NewDefaultCertPool()
var defaultCertPool *x509.CertPool = netxlite.NewDefaultCertPool()
// NewResolver creates a new resolver from the specified config
func NewResolver(config Config) Resolver {
@@ -312,7 +311,7 @@ func NewDNSClientWithOverrides(config Config, URL, hostOverride, SNIOverride,
return c, err
}
config.TLSConfig = &tls.Config{ServerName: SNIOverride}
if err := tlsx.ConfigureTLSVersion(config.TLSConfig, TLSVersion); err != nil {
if err := netxlite.ConfigureTLSVersion(config.TLSConfig, TLSVersion); err != nil {
return c, err
}
switch resolverURL.Scheme {
+1 -2
View File
@@ -13,7 +13,6 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/netx/httptransport"
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsdialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -848,7 +847,7 @@ func TestNewDNSClientBadUDPEndpoint(t *testing.T) {
func TestNewDNSCLientWithInvalidTLSVersion(t *testing.T) {
_, err := netx.NewDNSClientWithOverrides(
netx.Config{}, "dot://8.8.8.8", "", "", "TLSv999")
if !errors.Is(err, tlsx.ErrInvalidTLSVersion) {
if !errors.Is(err, netxlite.ErrInvalidTLSVersion) {
t.Fatalf("not the error we expected: %+v", err)
}
}
+3 -3
View File
@@ -6,8 +6,8 @@ import (
"time"
"github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// HandshakeSaver saves events occurring during the handshake
@@ -50,12 +50,12 @@ func (h HandshakeSaver) DialContext(ctx context.Context, network string,
Duration: stop.Sub(start),
Name: "quic_handshake_done",
NoTLSVerify: tlsCfg.InsecureSkipVerify,
TLSCipherSuite: tlsx.CipherSuiteString(state.CipherSuite),
TLSCipherSuite: netxlite.TLSCipherSuiteString(state.CipherSuite),
TLSNegotiatedProto: state.NegotiatedProtocol,
TLSNextProtos: tlsCfg.NextProtos,
TLSPeerCerts: trace.PeerCerts(state, err),
TLSServerName: tlsCfg.ServerName,
TLSVersion: tlsx.VersionString(state.Version),
TLSVersion: netxlite.TLSVersionString(state.Version),
Time: stop,
})
return sess, nil
+3 -3
View File
@@ -6,8 +6,8 @@ import (
"net"
"time"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// SaverTLSHandshaker saves events occurring during the handshake
@@ -35,12 +35,12 @@ func (h SaverTLSHandshaker) Handshake(
Err: err,
Name: "tls_handshake_done",
NoTLSVerify: config.InsecureSkipVerify,
TLSCipherSuite: tlsx.CipherSuiteString(state.CipherSuite),
TLSCipherSuite: netxlite.TLSCipherSuiteString(state.CipherSuite),
TLSNegotiatedProto: state.NegotiatedProtocol,
TLSNextProtos: config.NextProtos,
TLSPeerCerts: trace.PeerCerts(state, err),
TLSServerName: config.ServerName,
TLSVersion: tlsx.VersionString(state.Version),
TLSVersion: netxlite.TLSVersionString(state.Version),
Time: stop,
})
return tlsconn, state, err
File diff suppressed because it is too large Load Diff
-86
View File
@@ -1,86 +0,0 @@
// +build ignore
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//
// Forked from github.com/certifi/gocertifi <https://git.io/JJjmG>.
//
// This script should not be invoked directly, rather it should be
// executed by running go generate ./... from toplevel dir.
package main
import (
"context"
"crypto/x509"
"log"
"net/http"
"os"
"strings"
"text/template"
"time"
"github.com/ooni/probe-cli/v3/internal/iox"
)
var tmpl = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
// {{ .Timestamp }}
// {{ .URL }}
package tlsx
//go:generate go run generate.go "{{ .URL }}"
const pemcerts string = ` + "`" + `
{{ .Bundle }}
` + "`" + `
`))
func main() {
if len(os.Args) != 2 || !strings.HasPrefix(os.Args[1], "https://") {
log.Fatal("usage: go run generate.go <url>")
}
url := os.Args[1]
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != 200 {
log.Fatal("expected 200, got", resp.StatusCode)
}
defer resp.Body.Close()
bundle, err := iox.ReadAllContext(context.Background(), resp.Body)
if err != nil {
log.Fatal(err)
}
pool := x509.NewCertPool()
if !pool.AppendCertsFromPEM(bundle) {
log.Fatalf("can't parse certificates from %s", url)
}
fp, err := os.Create("certifi.go")
if err != nil {
log.Fatal(err)
}
err = tmpl.Execute(fp, struct {
Timestamp time.Time
URL string
Bundle string
}{
Timestamp: time.Now(),
URL: url,
Bundle: string(bundle),
})
if err != nil {
log.Fatal(err)
}
if err := fp.Close(); err != nil {
log.Fatal(err)
}
}
-103
View File
@@ -1,103 +0,0 @@
// Package tlsx contains TLS extensions
package tlsx
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
)
var (
tlsVersionString = map[uint16]string{
tls.VersionSSL30: "SSLv3",
tls.VersionTLS10: "TLSv1",
tls.VersionTLS11: "TLSv1.1",
tls.VersionTLS12: "TLSv1.2",
tls.VersionTLS13: "TLSv1.3",
0: "", // guarantee correct behaviour
}
tlsCipherSuiteString = map[uint16]string{
tls.TLS_RSA_WITH_RC4_128_SHA: "TLS_RSA_WITH_RC4_128_SHA",
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
tls.TLS_RSA_WITH_AES_128_CBC_SHA: "TLS_RSA_WITH_AES_128_CBC_SHA",
tls.TLS_RSA_WITH_AES_256_CBC_SHA: "TLS_RSA_WITH_AES_256_CBC_SHA",
tls.TLS_RSA_WITH_AES_128_CBC_SHA256: "TLS_RSA_WITH_AES_128_CBC_SHA256",
tls.TLS_RSA_WITH_AES_128_GCM_SHA256: "TLS_RSA_WITH_AES_128_GCM_SHA256",
tls.TLS_RSA_WITH_AES_256_GCM_SHA384: "TLS_RSA_WITH_AES_256_GCM_SHA384",
tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
tls.TLS_AES_128_GCM_SHA256: "TLS_AES_128_GCM_SHA256",
tls.TLS_AES_256_GCM_SHA384: "TLS_AES_256_GCM_SHA384",
tls.TLS_CHACHA20_POLY1305_SHA256: "TLS_CHACHA20_POLY1305_SHA256",
0: "", // guarantee correct behaviour
}
)
// VersionString returns a TLS version string.
func VersionString(value uint16) string {
if str, found := tlsVersionString[value]; found {
return str
}
return fmt.Sprintf("TLS_VERSION_UNKNOWN_%d", value)
}
// CipherSuiteString returns the TLS cipher suite as a string.
func CipherSuiteString(value uint16) string {
if str, found := tlsCipherSuiteString[value]; found {
return str
}
return fmt.Sprintf("TLS_CIPHER_SUITE_UNKNOWN_%d", value)
}
// NewDefaultCertPool returns a copy of the default x509
// certificate pool that we bundle from Mozilla.
func NewDefaultCertPool() *x509.CertPool {
pool := x509.NewCertPool()
// Assumption: AppendCertsFromPEM cannot fail because we
// run this function already in the generate.go file
pool.AppendCertsFromPEM([]byte(pemcerts))
return pool
}
// ErrInvalidTLSVersion indicates that you passed us a string
// that does not represent a valid TLS version.
var ErrInvalidTLSVersion = errors.New("invalid TLS version")
// ConfigureTLSVersion configures the correct TLS version into
// the specified *tls.Config or returns an error.
func ConfigureTLSVersion(config *tls.Config, version string) error {
switch version {
case "TLSv1.3":
config.MinVersion = tls.VersionTLS13
config.MaxVersion = tls.VersionTLS13
case "TLSv1.2":
config.MinVersion = tls.VersionTLS12
config.MaxVersion = tls.VersionTLS12
case "TLSv1.1":
config.MinVersion = tls.VersionTLS11
config.MaxVersion = tls.VersionTLS11
case "TLSv1.0", "TLSv1":
config.MinVersion = tls.VersionTLS10
config.MaxVersion = tls.VersionTLS10
case "":
// nothing
default:
return ErrInvalidTLSVersion
}
return nil
}
-105
View File
@@ -1,105 +0,0 @@
package tlsx
import (
"crypto/tls"
"errors"
"testing"
)
func TestVersionString(t *testing.T) {
if VersionString(tls.VersionTLS13) != "TLSv1.3" {
t.Fatal("not working for existing version")
}
if VersionString(1) != "TLS_VERSION_UNKNOWN_1" {
t.Fatal("not working for nonexisting version")
}
if VersionString(0) != "" {
t.Fatal("not working for zero version")
}
}
func TestCipherSuite(t *testing.T) {
if CipherSuiteString(tls.TLS_AES_128_GCM_SHA256) != "TLS_AES_128_GCM_SHA256" {
t.Fatal("not working for existing cipher suite")
}
if CipherSuiteString(1) != "TLS_CIPHER_SUITE_UNKNOWN_1" {
t.Fatal("not working for nonexisting cipher suite")
}
if CipherSuiteString(0) != "" {
t.Fatal("not working for zero cipher suite")
}
}
func TestNewDefaultCertPoolWorks(t *testing.T) {
pool := NewDefaultCertPool()
if pool == nil {
t.Fatal("expected non-nil value here")
}
}
func TestConfigureTLSVersion(t *testing.T) {
tests := []struct {
name string
version string
wantErr error
versionMin int
versionMax int
}{{
name: "with TLSv1.3",
version: "TLSv1.3",
wantErr: nil,
versionMin: tls.VersionTLS13,
versionMax: tls.VersionTLS13,
}, {
name: "with TLSv1.2",
version: "TLSv1.2",
wantErr: nil,
versionMin: tls.VersionTLS12,
versionMax: tls.VersionTLS12,
}, {
name: "with TLSv1.1",
version: "TLSv1.1",
wantErr: nil,
versionMin: tls.VersionTLS11,
versionMax: tls.VersionTLS11,
}, {
name: "with TLSv1.0",
version: "TLSv1.0",
wantErr: nil,
versionMin: tls.VersionTLS10,
versionMax: tls.VersionTLS10,
}, {
name: "with TLSv1",
version: "TLSv1",
wantErr: nil,
versionMin: tls.VersionTLS10,
versionMax: tls.VersionTLS10,
}, {
name: "with default",
version: "",
wantErr: nil,
versionMin: 0,
versionMax: 0,
}, {
name: "with invalid version",
version: "TLSv999",
wantErr: ErrInvalidTLSVersion,
versionMin: 0,
versionMax: 0,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
conf := new(tls.Config)
err := ConfigureTLSVersion(conf, tt.version)
if !errors.Is(err, tt.wantErr) {
t.Fatalf("not the error we expected: %+v", err)
}
if conf.MinVersion != uint16(tt.versionMin) {
t.Fatalf("not the min version we expected: %+v", conf.MinVersion)
}
if conf.MaxVersion != uint16(tt.versionMax) {
t.Fatalf("not the max version we expected: %+v", conf.MaxVersion)
}
})
}
}