Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

23 changed files with 839 additions and 119 deletions

View File

@ -1,11 +1,11 @@
package application
import (
"git.openprivacy.ca/openprivacy/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go"
"git.openprivacy.ca/openprivacy/libricochet-go/connection"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/identity"
"git.openprivacy.ca/openprivacy/log"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"net"
"sync"
)
@ -136,8 +136,6 @@ func (ra *RicochetApplication) Close(onion string) {
// ConnectionCount returns the number of concurrent connections to the application
func (ra *RicochetApplication) ConnectionCount() int {
ra.lock.Lock()
defer ra.lock.Unlock()
return len(ra.instances)
}

View File

@ -2,12 +2,12 @@ package alicebot
import (
"crypto/rand"
"git.openprivacy.ca/openprivacy/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/connection"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/identity"
"git.openprivacy.ca/openprivacy/log"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"golang.org/x/crypto/ed25519"
"os"
"time"

View File

@ -6,10 +6,10 @@ import (
"git.openprivacy.ca/openprivacy/libricochet-go/application/examples/echobot/alicebot"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/identity"
"git.openprivacy.ca/openprivacy/log"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"time"
"git.openprivacy.ca/openprivacy/connectivity/tor"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"golang.org/x/crypto/ed25519"
"os"
)
@ -75,7 +75,7 @@ func main() {
log.AddEverythingFromPattern("connectivity")
// Set up Tor
acn, err := tor.NewTorACN(".", "")
acn, err := connectivity.StartTor(".", "")
if err != nil {
log.Errorf("Unable to start Tor: %v", err)
os.Exit(1)

View File

@ -2,14 +2,13 @@ package inbound
import (
"crypto/rand"
tapirutils "cwtch.im/tapir/utils"
"errors"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/identity"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"git.openprivacy.ca/openprivacy/libricochet-go/wire/auth/3edh"
"git.openprivacy.ca/openprivacy/libricochet-go/wire/control"
"git.openprivacy.ca/openprivacy/log"
"github.com/golang/protobuf/proto"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/nacl/secretbox"
@ -130,20 +129,10 @@ func (ah *Server3DHAuthChannel) Packet(data []byte) {
secret1 := ah.ServerIdentity.EDH(ah.clientEphmeralPublicKey)
// Server Ephemeral <-> Client Identity
secret2, err := tapirutils.EDH(ah.serverEphemeralPrivateKey, ah.clientPubKey)
if err != nil {
ah.channel.CloseChannel()
return
}
secret2 := utils.EDH(ah.serverEphemeralPrivateKey, ah.clientPubKey)
// Ephemeral <-> Ephemeral
secret3, err := tapirutils.EDH(ah.serverEphemeralPrivateKey, ah.clientEphmeralPublicKey)
if err != nil {
ah.channel.CloseChannel()
return
}
secret3 := utils.EDH(ah.serverEphemeralPrivateKey, ah.clientEphmeralPublicKey)
var secret [96]byte
copy(secret[0:32], secret1[:])

View File

@ -2,14 +2,13 @@ package outbound
import (
"crypto/rand"
tapirutils "cwtch.im/tapir/utils"
"errors"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/identity"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"git.openprivacy.ca/openprivacy/libricochet-go/wire/auth/3edh"
"git.openprivacy.ca/openprivacy/libricochet-go/wire/control"
"git.openprivacy.ca/openprivacy/log"
"github.com/golang/protobuf/proto"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/nacl/secretbox"
@ -118,23 +117,13 @@ func (ah *Client3DHAuthChannel) OpenOutboundResult(err error, crm *Protocol_Data
log.Debugf("Public Keys Exchanged. Deriving Encryption Keys and Sending Encrypted Test Message")
// Server Ephemeral <-> Client Identity
secret1, err := tapirutils.EDH(ah.clientEphemeralPrivateKey, ah.serverPubKey)
if err != nil {
ah.channel.CloseChannel()
return
}
secret1 := utils.EDH(ah.clientEphemeralPrivateKey, ah.serverPubKey)
// Server Identity <-> Client Ephemeral
secret2 := ah.ClientIdentity.EDH(ah.serverEphemeralPublicKey)
// Ephemeral <-> Ephemeral
secret3, err := tapirutils.EDH(ah.clientEphemeralPrivateKey, ah.serverEphemeralPublicKey)
if err != nil {
ah.channel.CloseChannel()
return
}
secret3 := utils.EDH(ah.clientEphemeralPrivateKey, ah.serverEphemeralPublicKey)
var secret [96]byte
copy(secret[0:32], secret1[:])

View File

@ -4,9 +4,9 @@ import (
"context"
"fmt"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"git.openprivacy.ca/openprivacy/libricochet-go/wire/control"
"git.openprivacy.ca/openprivacy/log"
"github.com/golang/protobuf/proto"
"io"
"sync"

View File

@ -3,9 +3,9 @@ package connection
import (
"errors"
"fmt"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"git.openprivacy.ca/openprivacy/libricochet-go/wire/control"
"git.openprivacy.ca/openprivacy/log"
)
// ControlChannel encapsulates logic for the control channel processing

46
connectivity/acn.go Normal file
View File

@ -0,0 +1,46 @@
package connectivity
import (
"net"
)
// PrivateKey represents a private key using an unspecified algorithm.
type PrivateKey interface{}
// ListenService is an address that was opened with Listen() and can Accept() new connections
type ListenService interface {
// AddressIdentity is the core "identity" part of an address, ex: rsjeuxzlexy4fvo75vrdtj37nrvlmvbw57n5mhypcjpzv3xkka3l4yyd
AddressIdentity() string
// AddressFull is the full network address, ex: rsjeuxzlexy4fvo75vrdtj37nrvlmvbw57n5mhypcjpzv3xkka3l4yyd.onion:9878
AddressFull() string
Accept() (net.Conn, error)
Close()
}
// ACN is Anonymous Communication Network implementation wrapper that supports Open for new connections and Listen to accept connections
type ACN interface {
// GetBootstrapStatus returns an int 0-100 on the percent the bootstrapping of the underlying network is at and an optional string message
GetBootstrapStatus() (int, string)
// WaitTillBootstrapped Blocks until underlying network is bootstrapped
WaitTillBootstrapped()
// Sets the calback function to be called when ACN status changes
SetStatusCallback(callback func(int, string))
// Restarts the underlying connection
Restart()
// Open takes a hostname and returns a net.conn to the derived endpoint
// Open allows a client to resolve various hostnames to connections
// The supported types are onions address are:
// * ricochet:jlq67qzo6s4yp3sp
// * jlq67qzo6s4yp3sp
// * 127.0.0.1:55555|jlq67qzo6s4yp3sp - Localhost Connection
Open(hostname string) (net.Conn, string, error)
// Listen takes a private key and a port and returns a ListenService for it
Listen(identity PrivateKey, port int) (ListenService, error)
Close()
}

View File

@ -0,0 +1,77 @@
package connectivity
import (
"fmt"
"net"
"strings"
)
type localListenService struct {
l net.Listener
}
type localProvider struct {
}
func (ls *localListenService) AddressFull() string {
return ls.l.Addr().String()
}
func (ls *localListenService) AddressIdentity() string {
return ls.l.Addr().String()
}
func (ls *localListenService) Accept() (net.Conn, error) {
return ls.l.Accept()
}
func (ls *localListenService) Close() {
ls.l.Close()
}
// GetBootstrapStatus returns an int 0-100 on the percent the bootstrapping of the underlying network is at and an optional string message
func (lp *localProvider) GetBootstrapStatus() (int, string) {
return 100, "Done"
}
func (lp *localProvider) SetStatusCallback(callback func(int, string)) {
// nop
}
// WaitTillBootstrapped Blocks until underlying network is bootstrapped
func (lp *localProvider) WaitTillBootstrapped() {
}
func (lp *localProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%v", port))
return &localListenService{l}, err
}
func (lp *localProvider) Open(hostname string) (net.Conn, string, error) {
// Localhost (127.0.0.1:55555|jlq67qzo6s4yp3sp) for testing
addrParts := strings.Split(hostname, "|")
tcpAddr, err := net.ResolveTCPAddr("tcp", addrParts[0])
if err != nil {
return nil, "", CannotResolveLocalTCPAddressError
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
return nil, "", CannotDialLocalTCPAddressError
}
// return just the onion address, not the local override for the hostname
return conn, addrParts[1], nil
}
func (lp *localProvider) Restart() {
//noop
}
func (lp *localProvider) Close() {
}
// LocalProvider returns a for testing use only local clearnet implementation of a ACN interface
func LocalProvider() ACN {
return &localProvider{}
}

View File

@ -0,0 +1,9 @@
// +build !windows
package connectivity
import (
"syscall"
)
var sysProcAttr = &syscall.SysProcAttr{}

View File

@ -0,0 +1,9 @@
// +build windows
package connectivity
import (
"syscall"
)
var sysProcAttr = &syscall.SysProcAttr{HideWindow: true}

382
connectivity/torProvider.go Normal file
View File

@ -0,0 +1,382 @@
package connectivity
import (
"context"
"errors"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"github.com/cretz/bine/control"
"github.com/cretz/bine/process"
"github.com/cretz/bine/tor"
bineed255192 "github.com/cretz/bine/torutil/ed25519"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/sha3"
"net"
"net/textproto"
"os"
"os/exec"
"path"
"regexp"
"strconv"
"strings"
"sync"
"time"
)
const (
// CannotResolveLocalTCPAddressError is thrown when a local ricochet connection has the wrong format.
CannotResolveLocalTCPAddressError = utils.Error("CannotResolveLocalTCPAddressError")
// CannotDialLocalTCPAddressError is thrown when a connection to a local ricochet address fails.
CannotDialLocalTCPAddressError = utils.Error("CannotDialLocalTCPAddressError")
// CannotDialRicochetAddressError is thrown when a connection to a ricochet address fails.
CannotDialRicochetAddressError = utils.Error("CannotDialRicochetAddressError")
)
const (
minStatusIntervalMs = 200
maxStatusIntervalMs = 2000
)
type onionListenService struct {
os *tor.OnionService
tp *torProvider
}
type torProvider struct {
t *tor.Tor
dialer *tor.Dialer
appDirectory string
bundeledTorPath string
lock sync.Mutex
breakChan chan bool
childListeners map[string]*onionListenService
statusCallback func(int, string)
}
func (ols *onionListenService) AddressFull() string {
return ols.os.Addr().String()
}
func (ols *onionListenService) AddressIdentity() string {
return ols.os.Addr().String()[:56]
}
func (ols *onionListenService) Accept() (net.Conn, error) {
return ols.os.Accept()
}
func (ols *onionListenService) Close() {
ols.tp.unregisterListener(ols.AddressIdentity())
ols.os.Close()
}
// GetBootstrapStatus returns an int -1 on error or 0-100 on the percent the bootstrapping of the underlying network is at and an optional string message
func (tp *torProvider) GetBootstrapStatus() (int, string) {
if tp.t == nil {
return -1, "error: no tor, trying to restart..."
}
kvs, err := tp.t.Control.GetInfo("status/bootstrap-phase")
if err != nil {
return -1, "error"
}
progress := 0
status := ""
if len(kvs) > 0 {
progRe := regexp.MustCompile("PROGRESS=([0-9]*)")
sumRe := regexp.MustCompile("SUMMARY=\"(.*)\"$")
if progMatches := progRe.FindStringSubmatch(kvs[0].Val); len(progMatches) > 1 {
progress, _ = strconv.Atoi(progMatches[1])
}
if statusMatches := sumRe.FindStringSubmatch(kvs[0].Val); len(statusMatches) > 1 {
status = statusMatches[1]
}
}
return progress, status
}
// WaitTillBootstrapped Blocks until underlying network is bootstrapped
func (tp *torProvider) WaitTillBootstrapped() {
for true {
progress, _ := tp.GetBootstrapStatus()
if progress == 100 {
break
}
time.Sleep(100 * time.Millisecond)
}
}
func (tp *torProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
var onion = ""
var privkey ed25519.PrivateKey
tp.lock.Lock()
defer tp.lock.Unlock()
if tp.t == nil {
return nil, errors.New("Tor Provider closed")
}
switch pk := identity.(type) {
case ed25519.PrivateKey:
privkey = pk
gpubk := pk.Public()
switch pubk := gpubk.(type) {
case ed25519.PublicKey:
onion = utils.GetTorV3Hostname(pubk)
}
}
// Hack around tor detached onions not having a more obvious resume mechanism
// So we use deterministic ports
seedbytes := sha3.New224().Sum([]byte(onion))
localport := int(seedbytes[0]) + (int(seedbytes[1]) << 8)
if localport < 1024 { // this is not uniformly random, but we don't need it to be
localport += 1024
}
localListener, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(localport))
conf := &tor.ListenConf{NoWait: true, Version3: true, Key: identity, RemotePorts: []int{port}, Detach: true, DiscardKey: true, LocalListener: localListener}
os, err := tp.t.Listen(nil, conf)
if err != nil && strings.Contains(err.Error(), "550 Unspecified Tor error: Onion address collision") {
os = &tor.OnionService{Tor: tp.t, LocalListener: localListener, ID: onion, Version3: true, Key: bineed255192.FromCryptoPrivateKey(privkey), ClientAuths: make(map[string]string, 0), RemotePorts: []int{port}}
err = nil
}
// Not set in t.Listen if supplied, we want it to handle this however
os.CloseLocalListenerOnClose = true
if err != nil {
return nil, err
}
ols := &onionListenService{os: os, tp: tp}
tp.childListeners[ols.AddressIdentity()] = ols
return ols, nil
}
func (tp *torProvider) Restart() {
if tp.statusCallback != nil {
tp.statusCallback(0, "rebooting")
}
tp.restart()
}
func (tp *torProvider) Open(hostname string) (net.Conn, string, error) {
tp.lock.Lock()
if tp.t == nil {
tp.lock.Unlock()
return nil, hostname, errors.New("Tor is offline")
}
tp.lock.Unlock()
resolvedHostname := hostname
if strings.HasPrefix(hostname, "ricochet:") {
addrParts := strings.Split(hostname, ":")
resolvedHostname = addrParts[1]
}
conn, err := tp.dialer.Dial("tcp", resolvedHostname+".onion:9878")
return conn, resolvedHostname, err
}
func (tp *torProvider) Close() {
for _, child := range tp.childListeners {
child.Close()
}
tp.lock.Lock()
defer tp.lock.Unlock()
tp.breakChan <- true
if tp.t != nil {
tp.t.Close()
tp.t = nil
}
}
func (tp *torProvider) SetStatusCallback(callback func(int, string)) {
tp.lock.Lock()
defer tp.lock.Unlock()
tp.statusCallback = callback
}
// StartTor creates/starts a Tor ACN and returns a usable ACN object
func StartTor(appDirectory string, bundledTorPath string) (ACN, error) {
tp, err := startTor(appDirectory, bundledTorPath)
if err == nil {
tp.dialer, err = tp.t.Dialer(nil, &tor.DialConf{})
if err == nil {
go tp.monitorRestart()
}
}
return tp, err
}
// newHideCmd creates a Creator function for bine which generates a cmd that one windows will hide the dosbox
func newHideCmd(exePath string) process.Creator {
return process.CmdCreatorFunc(func(ctx context.Context, args ...string) (*exec.Cmd, error) {
cmd := exec.CommandContext(ctx, exePath, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = sysProcAttr
return cmd, nil
})
}
func startTor(appDirectory string, bundledTorPath string) (*torProvider, error) {
dataDir := path.Join(appDirectory, "tor")
os.MkdirAll(dataDir, 0700)
tp := &torProvider{appDirectory: appDirectory, bundeledTorPath: bundledTorPath, childListeners: make(map[string]*onionListenService), breakChan: make(chan bool), statusCallback: nil}
// attempt connect to system tor
log.Debugf("dialing system tor control port\n")
controlport, err := dialControlPort(9051)
if err == nil {
// TODO: configurable auth
err := controlport.Authenticate("")
if err == nil {
log.Debugln("connected to control port")
pinfo, err := controlport.ProtocolInfo()
if err == nil && minTorVersionReqs(pinfo.TorVersion) {
log.Debugln("OK version " + pinfo.TorVersion)
tp.t = createFromExisting(controlport, dataDir)
return tp, nil
}
controlport.Close()
}
}
// if not, try running system tor
if checkCmdlineTorVersion("tor") {
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, DebugWriter: nil, ProcessCreator: newHideCmd("tor")})
if err == nil {
tp.t = t
return tp, nil
}
log.Debugf("Error connecting to self-run system tor: %v\n", err)
}
// try running bundledTor
if bundledTorPath != "" && checkCmdlineTorVersion(bundledTorPath) {
log.Debugln("using bundled tor '" + bundledTorPath + "'")
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, ExePath: bundledTorPath, DebugWriter: nil, ProcessCreator: newHideCmd(bundledTorPath)})
if err != nil {
log.Debugf("Error running bundled tor: %v\n", err)
}
tp.t = t
return tp, err
}
return nil, errors.New("Could not connect to or start Tor that met requirments (min Tor version 0.3.5.x)")
}
func (tp *torProvider) unregisterListener(id string) {
tp.lock.Lock()
defer tp.lock.Unlock()
delete(tp.childListeners, id)
}
func (tp *torProvider) monitorRestart() {
lastBootstrapProgress := 0
interval := minStatusIntervalMs
for {
select {
case <-time.After(time.Millisecond * time.Duration(interval)):
prog, status := tp.GetBootstrapStatus()
if prog == -1 && tp.t != nil {
if tp.statusCallback != nil {
tp.statusCallback(prog, status)
}
tp.restart()
interval = minStatusIntervalMs
} else if prog != lastBootstrapProgress {
if tp.statusCallback != nil {
tp.statusCallback(prog, status)
}
interval = minStatusIntervalMs
} else {
if interval < maxStatusIntervalMs {
interval *= 2
}
}
lastBootstrapProgress = prog
case <-tp.breakChan:
return
}
}
}
func (tp *torProvider) restart() {
for _, child := range tp.childListeners {
child.Close()
}
tp.lock.Lock()
defer tp.lock.Unlock()
tp.t.Close()
tp.t = nil
for {
newTp, err := startTor(tp.appDirectory, tp.bundeledTorPath)
if err == nil {
tp.t = newTp.t
tp.dialer, _ = tp.t.Dialer(nil, &tor.DialConf{})
return
}
}
}
func createFromExisting(controlport *control.Conn, datadir string) *tor.Tor {
t := &tor.Tor{
Process: nil,
Control: controlport,
ProcessCancelFunc: nil,
DataDir: datadir,
DeleteDataDirOnClose: false,
DebugWriter: nil,
StopProcessOnClose: false,
GeoIPCreatedFile: "",
GeoIPv6CreatedFile: "",
}
t.Control.DebugWriter = t.DebugWriter
t.EnableNetwork(nil, true)
return t
}
func checkCmdlineTorVersion(torCmd string) bool {
cmd := exec.Command(torCmd, "--version")
cmd.SysProcAttr = sysProcAttr
out, err := cmd.CombinedOutput()
re := regexp.MustCompile("[0-1]\\.[0-9]\\.[0-9]\\.[0-9]")
sysTorVersion := re.Find(out)
log.Infoln("tor version: " + string(sysTorVersion))
return err == nil && minTorVersionReqs(string(sysTorVersion))
}
// returns true if supplied version meets our min requirments
// min requirement: 0.3.5.x
func minTorVersionReqs(torversion string) bool {
torversions := strings.Split(torversion, ".") //eg: 0.3.4.8 or 0.3.5.1-alpha
log.Debugf("torversions: %v", torversions)
tva, _ := strconv.Atoi(torversions[0])
tvb, _ := strconv.Atoi(torversions[1])
tvc, _ := strconv.Atoi(torversions[2])
return tva > 0 || (tva == 0 && (tvb > 3 || (tvb == 3 && tvc >= 5)))
}
func dialControlPort(port int) (*control.Conn, error) {
textConn, err := textproto.Dial("tcp", "127.0.0.1:"+strconv.Itoa(port))
if err != nil {
return nil, err
}
return control.NewConn(textConn), nil
}

View File

@ -0,0 +1,30 @@
package connectivity
import (
"fmt"
"testing"
)
func getStatusCallback(progChan chan int) func(int, string) {
return func(prog int, status string) {
fmt.Printf("%v %v\n", prog, status)
progChan <- prog
}
}
func TestTorProvider(t *testing.T) {
progChan := make(chan int)
acn, err := StartTor(".", "")
if err != nil {
t.Error(err)
return
}
acn.SetStatusCallback(getStatusCallback(progChan))
progress := 0
for progress < 100 {
progress = <-progChan
}
acn.Close()
}

16
go.mod
View File

@ -1,11 +1,13 @@
module git.openprivacy.ca/openprivacy/libricochet-go
go 1.14
require (
cwtch.im/tapir v0.1.18
git.openprivacy.ca/openprivacy/connectivity v1.1.1
git.openprivacy.ca/openprivacy/log v1.0.0
github.com/golang/protobuf v1.3.5
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca
github.com/golang/protobuf v1.2.0
github.com/stretchr/testify v1.3.0 // indirect
golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 // indirect
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
)
go 1.13

73
go.sum
View File

@ -1,66 +1,21 @@
cwtch.im/tapir v0.1.18 h1:Fs/jL9ZRyel/A1D/BYzIPEVQau8y5BJg44yA+GQDbSM=
cwtch.im/tapir v0.1.18/go.mod h1:/IrAI6CBHfgzsfgRT8WHVb1P9fCCz7+45hfsdkKn8Zg=
git.openprivacy.ca/openprivacy/connectivity v1.1.0/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E=
git.openprivacy.ca/openprivacy/connectivity v1.1.1 h1:hKxBOmxP7Jdu3K1BJ93mRtKNiWUoP6YHt/o2snE2Z0w=
git.openprivacy.ca/openprivacy/connectivity v1.1.1/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E=
git.openprivacy.ca/openprivacy/log v1.0.0 h1:Rvqm1weUdR4AOnJ79b1upHCc9vC/QF1rhSD2Um7sr1Y=
git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
github.com/cretz/bine v0.1.0 h1:1/fvhLE+fk0bPzjdO5Ci+0ComYxEMuB1JhM4X5skT3g=
github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw=
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 h1:IhZPbxNd1UjBCaD5AfpSSbJTRlp+ZSuyuH5uoksNS04=
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b h1:Ib/yptP38nXZFMwqWSip+OKuMP9OkyDe3p+DssP8n9w=
golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View File

@ -3,7 +3,6 @@ package identity
import (
"crypto"
"crypto/rsa"
tapirutils "cwtch.im/tapir/utils"
"encoding/asn1"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"golang.org/x/crypto/ed25519"
@ -69,7 +68,7 @@ func (i *Identity) PublicKeyBytes() []byte {
// EDH performs a diffie helman operation on this identities private key with the given public key.
func (i *Identity) EDH(key ed25519.PublicKey) []byte {
secret, _ := tapirutils.EDH(*i.edpk, key)
secret := utils.EDH(*i.edpk, key)
return secret[:]
}

219
log/log.go Normal file
View File

@ -0,0 +1,219 @@
package log
import (
"fmt"
golog "log"
"os"
"runtime"
"strings"
)
// Level indicates the level a log should be classified at
type Level int
// The possible levels a log can have
const (
LevelDebug Level = iota + 1
LevelInfo
LevelWarn
LevelError
)
var levelString = map[Level]string{LevelDebug: "[DBUG]", LevelInfo: "[INFO]", LevelWarn: "[WARN]", LevelError: "[ERR ]"}
// Logger is a go Logger wrapper that adds log levels and pattern filtering
// It allows high level 'log level' filtering broadly
// It allows allows two addition levels of filtering:
// everythingFrom which allows inclusion of packages/patterns along with general logging
// nothingExcept which allows focusing on just listed areas
type Logger struct {
logger *golog.Logger
level Level
nothingExceptPatterns []string
everythingFromPatterns []string
excludeFromPatterns []string
}
// New returns a new Logger with a filter set to the supplied level
func New(level Level) *Logger {
return &Logger{logger: golog.New(os.Stderr, "", golog.Ldate|golog.Ltime), level: level, everythingFromPatterns: make([]string, 0), nothingExceptPatterns: make([]string, 0)}
}
// NewFile returns a new Logger that logs to the supplied file with a filter set to the supplied level
func NewFile(level Level, filename string) (*Logger, error) {
logfile, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return nil, err
}
return &Logger{logger: golog.New(logfile, "", golog.Ldate|golog.Ltime), level: level, everythingFromPatterns: make([]string, 0), nothingExceptPatterns: make([]string, 0)}, nil
}
var std = New(LevelWarn)
// SetStd sets the default logger all other functions use
func SetStd(logger *Logger) {
std = logger
}
// filter
func (l *Logger) filter(level Level) bool {
_, file, _, ok := runtime.Caller(3)
if !ok {
file = "???"
}
for _, pattern := range l.excludeFromPatterns {
if strings.Contains(file, pattern) {
return false
}
}
for _, pattern := range l.everythingFromPatterns {
if strings.Contains(file, pattern) {
return true
}
}
for _, pattern := range l.nothingExceptPatterns {
if strings.Contains(file, pattern) {
return true
}
}
if len(l.nothingExceptPatterns) > 0 {
return false
}
return l.aboveLevel(level)
}
func (l *Logger) aboveLevel(level Level) bool {
return level >= l.level
}
// SetLevel adjusts the output filter by logging level
func (l *Logger) SetLevel(level Level) {
l.level = level
}
// AddNothingExceptFilter enables strong filtering showing logs only for things on the approved list, adding this pattern to the list
func (l *Logger) AddNothingExceptFilter(pattern string) {
l.nothingExceptPatterns = append(l.nothingExceptPatterns, pattern)
}
// AddEverythingFromPattern adds a pattern to skip log level filtering, guaranteeing all logs matching the pattern are seen
func (l *Logger) AddEverythingFromPattern(pattern string) {
l.everythingFromPatterns = append(l.everythingFromPatterns, pattern)
}
// ExcludeFromPattern adds a pattern to exclude logs from
func (l *Logger) ExcludeFromPattern(pattern string) {
l.excludeFromPatterns = append(l.excludeFromPatterns, pattern)
}
func (l *Logger) header(level Level) string {
_, file, _, ok := runtime.Caller(3)
if !ok {
file = "???"
} else {
short := file
count := 0
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
short = file[i+1:]
count++
if count == 2 {
break
}
}
}
file = short
}
return file + " " + levelString[level] + " "
}
// Printf outputs the format and variables, assuming it passes the filter levels
func (l *Logger) Printf(level Level, format string, v ...interface{}) {
if l.filter(level) {
l.logger.Output(3, l.header(level)+fmt.Sprintf(format, v...))
}
}
// Println outputs the variables assuming the filter levels are passed
func (l *Logger) Println(level Level, v ...interface{}) {
if l.filter(level) {
l.logger.Output(3, l.header(level)+fmt.Sprintln(v...))
}
}
// SetLevel changes the filtering level of the system logger
func SetLevel(level Level) {
std.SetLevel(level)
}
// AddNothingExceptFilter enables strong filtering showing logs only for things on the approved list, adding this pattern to the list
func AddNothingExceptFilter(pattern string) {
std.AddNothingExceptFilter(pattern)
}
// AddEverythingFromPattern adds a pattern to skip log level filtering, guaranteeing all logs matching the pattern are seen
func AddEverythingFromPattern(pattern string) {
std.AddEverythingFromPattern(pattern)
}
// ExcludeFromPattern adds a pattern to exclude logs from
func ExcludeFromPattern(pattern string) {
std.ExcludeFromPattern(pattern)
}
// Printf outputs the format with variables assuming it passes the filter level
func Printf(level Level, format string, v ...interface{}) {
std.Printf(level, format, v...)
}
// Println outputs the varibles assuming they pass the filter level
func Println(level Level, v ...interface{}) {
std.Println(level, v...)
}
// Debugf outputs the format and variables at the Debug level
func Debugf(format string, v ...interface{}) {
std.Printf(LevelDebug, format, v...)
}
// Infof outputs the format and variables at the Info level
func Infof(format string, v ...interface{}) {
std.Printf(LevelInfo, format, v...)
}
// Warnf outputs the format and variables at the Warning level
func Warnf(format string, v ...interface{}) {
std.Printf(LevelWarn, format, v...)
}
// Errorf outputs the format and variables at the Error level
func Errorf(format string, v ...interface{}) {
std.Printf(LevelError, format, v...)
}
// Debugln outputs the variables at the Debug level
func Debugln(v ...interface{}) {
std.Println(LevelDebug, v...)
}
// Infoln outputs the variables at the Info level
func Infoln(v ...interface{}) {
std.Println(LevelInfo, v...)
}
// Warnln outputs the variables at the Warn level
func Warnln(v ...interface{}) {
std.Println(LevelWarn, v...)
}
// Errorln outputs the variables at the Error level
func Errorln(v ...interface{}) {
std.Println(LevelError, v...)
}

View File

@ -1,8 +1,8 @@
package goricochet
import (
"git.openprivacy.ca/openprivacy/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/connection"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"io"
"net"

View File

@ -1,7 +1,7 @@
package goricochet
import (
"git.openprivacy.ca/openprivacy/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"net"
"testing"
"time"
@ -19,7 +19,7 @@ func SimpleServer() {
}
func TestRicochetOpen(t *testing.T) {
acn := connectivity.NewLocalACN()
acn := connectivity.LocalProvider()
go SimpleServer()
// Wait for Server to Initialize
time.Sleep(time.Second)
@ -46,7 +46,7 @@ func BadServer() {
}
func TestRicochetOpenWithError(t *testing.T) {
acn := connectivity.NewLocalACN()
acn := connectivity.LocalProvider()
go BadServer()
// Wait for Server to Initialize
time.Sleep(time.Second)
@ -57,7 +57,7 @@ func TestRicochetOpenWithError(t *testing.T) {
}
func TestRicochetOpenWithNoServer(t *testing.T) {
acn := connectivity.NewLocalACN()
acn := connectivity.LocalProvider()
_, err := Open(acn, "127.0.0.1:11002|abcdefghijklmno.onion")
if err == nil {
t.Errorf("Open should have failed because of bad version negotiation.")

View File

@ -2,12 +2,12 @@ package testing
import (
"fmt"
"git.openprivacy.ca/openprivacy/connectivity/tor"
"git.openprivacy.ca/openprivacy/libricochet-go/application"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/identity"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"git.openprivacy.ca/openprivacy/log"
"runtime"
"strconv"
"sync"
@ -96,7 +96,7 @@ func TestApplicationIntegration(t *testing.T) {
log.SetLevel(log.LevelDebug)
startGoRoutines := runtime.NumGoroutine()
acn, err := tor.NewTorACN(".", "")
acn, err := connectivity.StartTor(".", "")
if err != nil {
t.Fatalf("Could not start tor: %v", err)
}

View File

@ -5,6 +5,8 @@ import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"github.com/agl/ed25519/extra25519"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/ed25519"
"io/ioutil"
"math"
@ -29,6 +31,21 @@ func GetRandNumber() *big.Int {
return num
}
// EDH implements diffie hellman using curve25519 keys derived from ed25519 keys
// NOTE: This uses a 3rd party library extra25519 as the key conversion is not in the core golang lib
// as such this definitely needs further review.
func EDH(privateKey ed25519.PrivateKey, remotePublicKey ed25519.PublicKey) [32]byte {
var privKeyBytes [64]byte
var remotePubKeyBytes [32]byte
copy(privKeyBytes[:], privateKey[:])
copy(remotePubKeyBytes[:], remotePublicKey[:])
var secret, curve25519priv, curve25519pub [32]byte
extra25519.PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes)
extra25519.PublicKeyToCurve25519(&curve25519pub, &remotePubKeyBytes)
curve25519.ScalarMult(&secret, &curve25519priv, &curve25519pub)
return secret
}
// GeneratePrivateKeyV3 cryptographically creats a new ed25519 key pair.
func GeneratePrivateKeyV3() (ed25519.PublicKey, ed25519.PrivateKey, error) {
return ed25519.GenerateKey(rand.Reader)

View File

@ -2,7 +2,6 @@ package utils
import (
"crypto/rand"
"cwtch.im/tapir/utils"
"golang.org/x/crypto/ed25519"
"math"
"testing"
@ -22,8 +21,8 @@ func TestLoadPrivateKey(t *testing.T) {
func TestEDH(t *testing.T) {
cpub, cpriv, _ := ed25519.GenerateKey(rand.Reader)
spub, spriv, _ := ed25519.GenerateKey(rand.Reader)
cedh, _ := utils.EDH(cpriv, spub)
sedh, _ := utils.EDH(spriv, cpub)
cedh := EDH(cpriv, spub)
sedh := EDH(spriv, cpub)
if string(cedh[:]) != string(sedh[:]) {
t.Errorf("Client and Server should see the same secret %v %v", cedh, sedh)
}

View File

@ -5,7 +5,7 @@ import (
"crypto/rand"
"encoding/binary"
"errors"
"git.openprivacy.ca/openprivacy/log"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"golang.org/x/crypto/nacl/secretbox"
"io"
"sync"