Skip to content

Commit

Permalink
fix(UNetStack): better compatibility with ooni/probe-cli models (#41)
Browse files Browse the repository at this point in the history
The refactoring at
45a7aa9
was a bit too aggressive and we have lost some degree of interface level
compatibility with ooni/probe-cli. Let's repair this:

* Add the `CACert` accessor required by ooni/probe-cli code.

* While there, also declare the accessor as being part of
`UnderlyingNetwork`.

* We have a slight issue with `ServerTLSConfig`, which is expected by
ooni/probe-cli and now is called `MustNewTLSConfig` and, additionally,
requires the names for which to generate the certificate. We will solve
these issues inside the ooni/probe-cli repository, but let's make sure
the `UNetStack` has the correct method.

Part of ooni/probe#2531
  • Loading branch information
bassosimone authored Sep 20, 2023
1 parent 45a7aa9 commit df36342
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
13 changes: 8 additions & 5 deletions ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ func caMustNewAuthority(name, organization string, validity time.Duration,
//
// SPDX-License-Identifier: Apache-2.0.
type CA struct {
ca *x509.Certificate
// CACert is the public certificate used by the CA.
CACert *x509.Certificate

// These fields are not exported
capriv any
keyID []byte
org string
Expand Down Expand Up @@ -120,7 +123,7 @@ func MustNewCAWithTimeNow(timeNow func() time.Time) *CA {
keyID := h.Sum(nil)

return &CA{
ca: ca,
CACert: ca,
capriv: privateKey,
priv: priv,
keyID: keyID,
Expand All @@ -132,7 +135,7 @@ func MustNewCAWithTimeNow(timeNow func() time.Time) *CA {
// CertPool returns an [x509.CertPool] using the given [*CA].
func (c *CA) CertPool() *x509.CertPool {
pool := x509.NewCertPool()
pool.AddCert(c.ca)
pool.AddCert(c.CACert)
return pool
}

Expand Down Expand Up @@ -185,13 +188,13 @@ func (c *CA) MustNewCertWithTimeNow(timeNow func() time.Time, commonName string,
}
}

raw := Must1(x509.CreateCertificate(rand.Reader, tmpl, c.ca, c.priv.Public(), c.capriv))
raw := Must1(x509.CreateCertificate(rand.Reader, tmpl, c.CACert, c.priv.Public(), c.capriv))

// Parse certificate bytes so that we have a leaf certificate.
x509c := Must1(x509.ParseCertificate(raw))

tlsc := &tls.Certificate{
Certificate: [][]byte{raw, c.ca.Raw},
Certificate: [][]byte{raw, c.CACert.Raw},
PrivateKey: c.priv,
Leaf: x509c,
}
Expand Down
3 changes: 3 additions & 0 deletions model.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ type UnderlyingNetwork interface {
// CA returns the CA we're using.
CA() *CA

// CACert returns the CA cert we're using.
CACert() *x509.Certificate

// DefaultCertPool returns the underlying cert pool to be used.
DefaultCertPool() *x509.CertPool

Expand Down
12 changes: 12 additions & 0 deletions unetstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package netem

import (
"context"
"crypto/tls"
"crypto/x509"
"net"
"net/netip"
Expand Down Expand Up @@ -108,6 +109,17 @@ func (gs *UNetStack) CA() *CA {
return gs.ca
}

// CACert implements UnderlyingNetwork.
func (gs *UNetStack) CACert() *x509.Certificate {
return gs.ca.CACert
}

// MustServerTLSConfig is used by [github.com/ooni/probe-cli] code
// when generating configuration for servers using TLS.
func (gs *UNetStack) MustServerTLSConfig(commonName string, extraNames ...string) *tls.Config {
return gs.ca.MustServerTLSConfig(commonName, extraNames...)
}

// Logger implements HTTPUnderlyingNetwork.
func (gs *UNetStack) Logger() Logger {
return gs.ns.logger
Expand Down

0 comments on commit df36342

Please sign in to comment.