Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
Sarah Jamie Lewis | 4129031391 | |
Sarah Jamie Lewis | 139a35c219 | |
Sarah Jamie Lewis | 4e4e3b4422 | |
Dan Ballard | 015307d907 | |
Sarah Jamie Lewis | 13effd5457 | |
Sarah Jamie Lewis | 9012720973 | |
Sarah Jamie Lewis | af2f509711 | |
Dan Ballard | eceddc676d |
89
.drone.yml
89
.drone.yml
|
@ -1,14 +1,14 @@
|
|||
workspace:
|
||||
base: /go
|
||||
path: src/cwtch.im/tapir
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: linux-test
|
||||
|
||||
pipeline:
|
||||
fetch:
|
||||
when:
|
||||
repo: cwtch.im/tapir
|
||||
branch: master
|
||||
event: [ push, pull_request ]
|
||||
image: golang
|
||||
steps:
|
||||
- name: fetch
|
||||
image: golang:1.17.5
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
commands:
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/tor
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/torrc
|
||||
|
@ -16,49 +16,58 @@ pipeline:
|
|||
- export GO111MODULE=on
|
||||
- go mod download
|
||||
- go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
quality:
|
||||
when:
|
||||
repo: cwtch.im/tapir
|
||||
branch: master
|
||||
event: [ push, pull_request ]
|
||||
image: golang
|
||||
- name: quality
|
||||
image: golang:1.17.5
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
commands:
|
||||
- staticcheck ./...
|
||||
units-tests:
|
||||
when:
|
||||
repo: cwtch.im/tapir
|
||||
branch: master
|
||||
event: [ push, pull_request ]
|
||||
image: golang
|
||||
- staticcheck ./...
|
||||
- name: units-tests
|
||||
image: golang:1.17.5
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
commands:
|
||||
- export PATH=$PATH:/go/src/cwtch.im/tapir
|
||||
- export PATH=`pwd`:$PATH
|
||||
- sh testing/tests.sh
|
||||
integ-test:
|
||||
when:
|
||||
repo: cwtch.im/tapir
|
||||
branch: master
|
||||
event: [ push, pull_request ]
|
||||
image: golang
|
||||
- name: integ-test
|
||||
image: golang:1.17.5
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
commands:
|
||||
- export PATH=$PATH:/go/src/cwtch.im/tapir
|
||||
- export PATH=`pwd`:$PATH
|
||||
- go test -race -v git.openprivacy.ca/cwtch.im/tapir/testing
|
||||
notify-email:
|
||||
- name: notify-email
|
||||
image: drillster/drone-email
|
||||
host: build.openprivacy.ca
|
||||
port: 25
|
||||
skip_verify: true
|
||||
from: drone@openprivacy.ca
|
||||
when:
|
||||
repo: cwtch.im/tapir
|
||||
branch: master
|
||||
event: [ push, pull_request ]
|
||||
status: [ failure ]
|
||||
notify-gogs:
|
||||
- name: notify-gogs
|
||||
image: openpriv/drone-gogs
|
||||
pull: if-not-exists
|
||||
when:
|
||||
repo: cwtch.im/tapir
|
||||
branch: master
|
||||
event: pull_request
|
||||
status: [ success, changed, failure ]
|
||||
secrets: [gogs_account_token]
|
||||
gogs_url: https://git.openprivacy.ca
|
||||
environment:
|
||||
GOGS_ACCOUNT_TOKEN:
|
||||
from_secret: gogs_account_token
|
||||
settings:
|
||||
gogs_url: https://git.openprivacy.ca
|
||||
|
||||
volumes:
|
||||
# gopath where bin and pkg lives to persist across steps
|
||||
- name: deps
|
||||
temp: {}
|
||||
|
||||
trigger:
|
||||
repo: cwtch.im/tapir
|
||||
branch: master
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
- tag
|
|
@ -10,7 +10,6 @@ import (
|
|||
"git.openprivacy.ca/openprivacy/connectivity"
|
||||
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||
"git.openprivacy.ca/openprivacy/log"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
@ -78,7 +77,7 @@ func TestTokenBoardApp(t *testing.T) {
|
|||
builder.WithSocksPort(9059).WithControlPort(9060).WithHashedPassword("tapir-integration-test").Build("./tor/torrc")
|
||||
torDataDir := ""
|
||||
var err error
|
||||
if torDataDir, err = ioutil.TempDir("./tor/", "data-dir-"); err != nil {
|
||||
if torDataDir, err = os.MkdirTemp("./tor/", "data-dir-"); err != nil {
|
||||
t.Fatalf("could not create data dir")
|
||||
}
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,6 +3,7 @@ module git.openprivacy.ca/cwtch.im/tapir
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.0.0
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.8.6
|
||||
git.openprivacy.ca/openprivacy/log v1.0.3
|
||||
github.com/gtank/merlin v0.1.1
|
||||
|
@ -12,7 +13,6 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
git.openprivacy.ca/openprivacy/bine v0.0.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect
|
||||
|
|
3
go.sum
3
go.sum
|
@ -22,8 +22,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
|
||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
@ -38,7 +36,6 @@ golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWI
|
|||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
@ -25,7 +25,6 @@ type State struct {
|
|||
Messages []Message
|
||||
}
|
||||
|
||||
//
|
||||
const (
|
||||
auditableDataStoreProtocol = "auditable-data-store"
|
||||
newMessage = "new-message"
|
||||
|
|
|
@ -12,8 +12,8 @@ import (
|
|||
// Transcript provides a consistent transcript primitive for our protocols
|
||||
//
|
||||
// We have the following goals:
|
||||
// - Allow sequential proofs over a common transcript (ensuring a single proof cannot be extracted standalone)
|
||||
// - be able to produce a human-readable transcript for auditing.
|
||||
// - Allow sequential proofs over a common transcript (ensuring a single proof cannot be extracted standalone)
|
||||
// - be able to produce a human-readable transcript for auditing.
|
||||
//
|
||||
// The design of this API was inspired by Merlin: https://docs.rs/crate/merlin/
|
||||
type Transcript struct {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
// DLEQProof encapsulates a Chaum-Pedersen DLEQ Proof
|
||||
//gut In Ernest F. Brickell, editor,CRYPTO’92,volume 740 ofLNCS, pages 89–105. Springer, Heidelberg,August 1993
|
||||
// gut In Ernest F. Brickell, editor,CRYPTO’92,volume 740 ofLNCS, pages 89–105. Springer, Heidelberg,August 1993
|
||||
type DLEQProof struct {
|
||||
C *ristretto.Scalar
|
||||
S *ristretto.Scalar
|
||||
|
@ -16,10 +16,11 @@ type DLEQProof struct {
|
|||
// DiscreteLogEquivalenceProof constructs a valid DLEQProof for the given parameters and transcript
|
||||
// Given Y = kX & Q = kP
|
||||
// Peggy: t := choose randomly from Zq
|
||||
// A := tX
|
||||
// B := tP
|
||||
// c := H(transcript(X,Y,P,Q,A,B))
|
||||
// s := (t + ck) mod q
|
||||
//
|
||||
// A := tX
|
||||
// B := tP
|
||||
// c := H(transcript(X,Y,P,Q,A,B))
|
||||
// s := (t + ck) mod q
|
||||
//
|
||||
// Sends c,s to Vicky
|
||||
func DiscreteLogEquivalenceProof(k *ristretto.Scalar, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) DLEQProof {
|
||||
|
@ -47,12 +48,14 @@ func DiscreteLogEquivalenceProof(k *ristretto.Scalar, X *ristretto.Element, Y *r
|
|||
// VerifyDiscreteLogEquivalenceProof verifies the DLEQ for the given parameters and transcript
|
||||
// Given Y = kX & Q = kP and Proof = (c,s)
|
||||
// Vicky: X' := sX
|
||||
// Y' := cY
|
||||
// P' := sP
|
||||
// Q' := cQ
|
||||
// A' = X'+Y' == sX + cY ?= sG + ckG == (s+ck)X == tX == A
|
||||
// B' = P'+Q' == sP + cQ ?= sP + ckP == (s+ck)P == tP == B
|
||||
// c' := H(transcript(X,Y,P,Q,A',B'))
|
||||
//
|
||||
// Y' := cY
|
||||
// P' := sP
|
||||
// Q' := cQ
|
||||
// A' = X'+Y' == sX + cY ?= sG + ckG == (s+ck)X == tX == A
|
||||
// B' = P'+Q' == sP + cQ ?= sP + ckP == (s+ck)P == tP == B
|
||||
// c' := H(transcript(X,Y,P,Q,A',B'))
|
||||
//
|
||||
// Tests c ?= c
|
||||
func VerifyDiscreteLogEquivalenceProof(dleq DLEQProof, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) bool {
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package privacypass
|
|||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.openprivacy.ca/cwtch.im/tapir/primitives/core"
|
||||
"git.openprivacy.ca/openprivacy/log"
|
||||
|
@ -122,3 +123,16 @@ func UnblindSignedTokenBatch(tokens []*Token, blindedTokens []BlindedToken, sign
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalJSON - in order to store tokens in a serialized form we need to expose the private, unexported value
|
||||
// `t`. Note that `r` is not needed to spend the token, and as such we effectively destroy it when we serialize.
|
||||
// Ideally, go would let us do this with an annotation, alas.
|
||||
func (t Token) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
T []byte `json:"t"`
|
||||
W *ristretto.Element
|
||||
}{
|
||||
T: t.t,
|
||||
W: t.W,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||
"git.openprivacy.ca/openprivacy/log"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
|
@ -69,7 +68,7 @@ func TestTapir(t *testing.T) {
|
|||
|
||||
torDataDir := ""
|
||||
var err error
|
||||
if torDataDir, err = ioutil.TempDir("./tor/", "data-dir-"); err != nil {
|
||||
if torDataDir, err = os.MkdirTemp("./tor/", "data-dir-"); err != nil {
|
||||
t.Fatalf("could not create data dir")
|
||||
}
|
||||
|
||||
|
@ -143,6 +142,10 @@ func connectclient(t *testing.T, client tapir.Service, key ed25519.PublicKey, gr
|
|||
conn, _ := client.GetConnection(torProvider.GetTorV3Hostname(key))
|
||||
log.Debugf("Client has Auth: %v", conn.HasCapability(applications.AuthCapability))
|
||||
|
||||
if conn.HasCapability(applications.AuthCapability) == false {
|
||||
t.Errorf("tapir auth failed")
|
||||
}
|
||||
|
||||
// attempt to send a message that is too long
|
||||
var long [8195]byte
|
||||
err := conn.Send(long[:])
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||
"git.openprivacy.ca/openprivacy/log"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
@ -30,7 +29,7 @@ func TestTapirMaliciousRemote(t *testing.T) {
|
|||
|
||||
torDataDir := ""
|
||||
var err error
|
||||
if torDataDir, err = ioutil.TempDir("./tor/", "data-dir-"); err != nil {
|
||||
if torDataDir, err = os.MkdirTemp("./tor/", "data-dir-"); err != nil {
|
||||
t.Fatalf("could not create data dir")
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ package utils
|
|||
|
||||
import (
|
||||
"crypto/sha512"
|
||||
"filippo.io/edwards25519"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// EDH implements diffie hellman using curve25519 keys derived from ed25519 keys
|
||||
|
@ -16,68 +16,23 @@ func EDH(privateKey ed25519.PrivateKey, remotePublicKey ed25519.PublicKey) ([]by
|
|||
var curve25519priv [32]byte
|
||||
|
||||
PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes)
|
||||
curve25519pub := ed25519PublicKeyToCurve25519(remotePublicKey)
|
||||
secret, err := curve25519.X25519(curve25519priv[:], curve25519pub[:])
|
||||
remoteCurve25519pub, err := ed25519PublicKeyToCurve25519New(remotePublicKey)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
secret, err := curve25519.X25519(curve25519priv[:], remoteCurve25519pub[:])
|
||||
return secret, err
|
||||
}
|
||||
|
||||
// https://github.com/FiloSottile/age/blob/master/internal/age/ssh.go#L174
|
||||
// Copyright 2019 Google LLC
|
||||
//
|
||||
//Redistribution and use in source and binary forms, with or without
|
||||
//modification, are permitted provided that the following conditions are
|
||||
//met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
//notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
//copyright notice, this list of conditions and the following disclaimer
|
||||
//in the documentation and/or other materials provided with the
|
||||
//distribution.
|
||||
// * Neither the name of Google LLC nor the names of its
|
||||
//contributors may be used to endorse or promote products derived from
|
||||
//this software without specific prior written permission.
|
||||
//
|
||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
//A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
//OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
//SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
//LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
//DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
//THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
//OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
var curve25519P, _ = new(big.Int).SetString("57896044618658097711785492504343953926634992332820282019728792003956564819949", 10)
|
||||
|
||||
func ed25519PublicKeyToCurve25519(pk ed25519.PublicKey) []byte {
|
||||
// ed25519.PublicKey is a little endian representation of the y-coordinate,
|
||||
// with the most significant bit set based on the sign of the x-coordinate.
|
||||
bigEndianY := make([]byte, ed25519.PublicKeySize)
|
||||
for i, b := range pk {
|
||||
bigEndianY[ed25519.PublicKeySize-i-1] = b
|
||||
// reproduced from https://github.com/FiloSottile/age/blob/main/agessh/agessh.go#L190
|
||||
func ed25519PublicKeyToCurve25519New(pk ed25519.PublicKey) ([]byte, error) {
|
||||
// See https://blog.filippo.io/using-ed25519-keys-for-encryption and
|
||||
// https://pkg.go.dev/filippo.io/edwards25519#Point.BytesMontgomery.
|
||||
p, err := new(edwards25519.Point).SetBytes(pk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bigEndianY[0] &= 0b0111_1111
|
||||
|
||||
// The Montgomery u-coordinate is derived through the bilinear map
|
||||
//
|
||||
// u = (1 + y) / (1 - y)
|
||||
//
|
||||
// See https://blog.filippo.io/using-ed25519-keys-for-encryption.
|
||||
y := new(big.Int).SetBytes(bigEndianY)
|
||||
denom := big.NewInt(1)
|
||||
denom.ModInverse(denom.Sub(denom, y), curve25519P) // 1 / (1 - y)
|
||||
u := y.Mul(y.Add(y, big.NewInt(1)), denom)
|
||||
u.Mod(u, curve25519P)
|
||||
|
||||
out := make([]byte, curve25519.PointSize)
|
||||
uBytes := u.Bytes()
|
||||
for i, b := range uBytes {
|
||||
out[len(uBytes)-i-1] = b
|
||||
}
|
||||
|
||||
return out
|
||||
return p.BytesMontgomery(), nil
|
||||
}
|
||||
|
||||
// PrivateKeyToCurve25519 converts an ed25519 private key into a corresponding
|
||||
|
|
Loading…
Reference in New Issue