feat: support embedding encrypted psiphon config (#285)
We use an optional build tag to hide this configuration. When you choose this configuration, you need to provide the encrypted config as well as the corresponding decryption key. This is not the final design. This is an interim design to start working and experimenting with this functionality. The general idea here is to support psiphon in the binaries we build without committing the psiphon config to the repository itself. Part of https://github.com/ooni/probe/issues/985
This commit is contained in:
parent
79e8424677
commit
c89ecce3e0
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/ooni/probe-cli/v3
|
|||
go 1.16
|
||||
|
||||
require (
|
||||
filippo.io/age v1.0.0-rc.1
|
||||
git.torproject.org/pluggable-transports/goptlib.git v1.1.0
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible
|
||||
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -6,6 +6,8 @@ dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl
|
|||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
filippo.io/age v1.0.0-rc.1 h1:jQ+dz16Xxx3W/WY+YS0J96nVAAidLHO3kfQe0eOmKgI=
|
||||
filippo.io/age v1.0.0-rc.1/go.mod h1:Vvd9IlwNo4Au31iqNZeZVnYtGcOf/wT4mtvZQ2ODlSk=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
git.schwanenlied.me/yawning/bsaes.git v0.0.0-20190320102049-26d1add596b6 h1:zOrl5/RvK48MxMrif6Z+/OpuYyRnvB+ZTrQWEV9VYb0=
|
||||
git.schwanenlied.me/yawning/bsaes.git v0.0.0-20190320102049-26d1add596b6/go.mod h1:BWqTsj8PgcPriQJGl7el20J/7TuT1d/hSyFDXMEpoEo=
|
||||
|
@ -518,6 +520,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -605,6 +608,7 @@ golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
2
internal/engine/.gitignore
vendored
2
internal/engine/.gitignore
vendored
|
@ -12,4 +12,6 @@
|
|||
/oohelper
|
||||
/oohelperd
|
||||
/oonipsiphon/
|
||||
/psiphon-config.json.age
|
||||
/psiphon-config.key
|
||||
.DS_Store
|
||||
|
|
|
@ -275,15 +275,6 @@ func (s *Session) DefaultHTTPClient() *http.Client {
|
|||
return &http.Client{Transport: s.httpDefaultTransport}
|
||||
}
|
||||
|
||||
// FetchPsiphonConfig fetches psiphon config from the API.
|
||||
func (s *Session) FetchPsiphonConfig(ctx context.Context) ([]byte, error) {
|
||||
clnt, err := s.NewOrchestraClient(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clnt.FetchPsiphonConfig(ctx)
|
||||
}
|
||||
|
||||
// FetchTorTargets fetches tor targets from the API.
|
||||
func (s *Session) FetchTorTargets(
|
||||
ctx context.Context, cc string) (map[string]model.TorTarget, error) {
|
||||
|
|
14
internal/engine/session_nopsiphon.go
Normal file
14
internal/engine/session_nopsiphon.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
// +build !ooni_psiphon_config
|
||||
|
||||
package engine
|
||||
|
||||
import "context"
|
||||
|
||||
// FetchPsiphonConfig fetches psiphon config from the API.
|
||||
func (s *Session) FetchPsiphonConfig(ctx context.Context) ([]byte, error) {
|
||||
clnt, err := s.NewOrchestraClient(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clnt.FetchPsiphonConfig(ctx)
|
||||
}
|
34
internal/engine/session_psiphon.go
Normal file
34
internal/engine/session_psiphon.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
// +build ooni_psiphon_config
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
_ "embed"
|
||||
"io/ioutil"
|
||||
|
||||
"filippo.io/age"
|
||||
)
|
||||
|
||||
//go:embed psiphon-config.json.age
|
||||
var psiphonConfigJSONAge []byte
|
||||
|
||||
//go:embed psiphon-config.key
|
||||
var psiphonConfigSecretKey string
|
||||
|
||||
// FetchPsiphonConfig decrypts psiphonConfigJSONAge using
|
||||
// filippo.io/age _and_ psiphonConfigSecretKey.
|
||||
func (s *Session) FetchPsiphonConfig(ctx context.Context) ([]byte, error) {
|
||||
key := "AGE-SECRET-KEY-1" + psiphonConfigSecretKey
|
||||
identity, err := age.ParseX25519Identity(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
input := bytes.NewReader(psiphonConfigJSONAge)
|
||||
output, err := age.Decrypt(input, identity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.ReadAll(output)
|
||||
}
|
19
internal/engine/session_psiphon_test.go
Normal file
19
internal/engine/session_psiphon_test.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
// +build ooni_psiphon_config
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSessionEmbeddedPsiphonConfig(t *testing.T) {
|
||||
s := &Session{}
|
||||
data, err := s.FetchPsiphonConfig(context.Background())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if data == nil {
|
||||
t.Fatal("expected non-nil data here")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user