Expose token.T in json + fix issue with new auth protocol #55

Merged
dan merged 3 commits from tokensfix into master 2022-10-25 20:56:11 +00:00
8 changed files with 42 additions and 25 deletions

View File

@ -10,7 +10,6 @@ import (
"git.openprivacy.ca/openprivacy/connectivity" "git.openprivacy.ca/openprivacy/connectivity"
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor" torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
"git.openprivacy.ca/openprivacy/log" "git.openprivacy.ca/openprivacy/log"
"io/ioutil"
"os" "os"
"runtime" "runtime"
"sync" "sync"
@ -78,7 +77,7 @@ func TestTokenBoardApp(t *testing.T) {
builder.WithSocksPort(9059).WithControlPort(9060).WithHashedPassword("tapir-integration-test").Build("./tor/torrc") builder.WithSocksPort(9059).WithControlPort(9060).WithHashedPassword("tapir-integration-test").Build("./tor/torrc")
torDataDir := "" torDataDir := ""
var err error 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") t.Fatalf("could not create data dir")
} }

View File

@ -25,7 +25,6 @@ type State struct {
Messages []Message Messages []Message
} }
//
const ( const (
auditableDataStoreProtocol = "auditable-data-store" auditableDataStoreProtocol = "auditable-data-store"
newMessage = "new-message" newMessage = "new-message"

View File

@ -12,8 +12,8 @@ import (
// Transcript provides a consistent transcript primitive for our protocols // Transcript provides a consistent transcript primitive for our protocols
// //
// We have the following goals: // We have the following goals:
// - Allow sequential proofs over a common transcript (ensuring a single proof cannot be extracted standalone) // - 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. // - be able to produce a human-readable transcript for auditing.
// //
// The design of this API was inspired by Merlin: https://docs.rs/crate/merlin/ // The design of this API was inspired by Merlin: https://docs.rs/crate/merlin/
type Transcript struct { type Transcript struct {

View File

@ -7,7 +7,7 @@ import (
) )
// DLEQProof encapsulates a Chaum-Pedersen DLEQ Proof // DLEQProof encapsulates a Chaum-Pedersen DLEQ Proof
//gut In Ernest F. Brickell, editor,CRYPTO92,volume 740 ofLNCS, pages 89105. Springer, Heidelberg,August 1993 // gut In Ernest F. Brickell, editor,CRYPTO92,volume 740 ofLNCS, pages 89105. Springer, Heidelberg,August 1993
type DLEQProof struct { type DLEQProof struct {
C *ristretto.Scalar C *ristretto.Scalar
S *ristretto.Scalar S *ristretto.Scalar
@ -16,10 +16,11 @@ type DLEQProof struct {
// DiscreteLogEquivalenceProof constructs a valid DLEQProof for the given parameters and transcript // DiscreteLogEquivalenceProof constructs a valid DLEQProof for the given parameters and transcript
// Given Y = kX & Q = kP // Given Y = kX & Q = kP
// Peggy: t := choose randomly from Zq // Peggy: t := choose randomly from Zq
// A := tX //
// B := tP // A := tX
// c := H(transcript(X,Y,P,Q,A,B)) // B := tP
// s := (t + ck) mod q // c := H(transcript(X,Y,P,Q,A,B))
// s := (t + ck) mod q
// //
// Sends c,s to Vicky // 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 { 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 // VerifyDiscreteLogEquivalenceProof verifies the DLEQ for the given parameters and transcript
// Given Y = kX & Q = kP and Proof = (c,s) // Given Y = kX & Q = kP and Proof = (c,s)
// Vicky: X' := sX // Vicky: X' := sX
// Y' := cY //
// P' := sP // Y' := cY
// Q' := cQ // P' := sP
// A' = X'+Y' == sX + cY ?= sG + ckG == (s+ck)X == tX == A // Q' := cQ
// B' = P'+Q' == sP + cQ ?= sP + ckP == (s+ck)P == tP == B // A' = X'+Y' == sX + cY ?= sG + ckG == (s+ck)X == tX == A
// c' := H(transcript(X,Y,P,Q,A',B')) // B' = P'+Q' == sP + cQ ?= sP + ckP == (s+ck)P == tP == B
// c' := H(transcript(X,Y,P,Q,A',B'))
//
// Tests c ?= c // Tests c ?= c
func VerifyDiscreteLogEquivalenceProof(dleq DLEQProof, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) bool { func VerifyDiscreteLogEquivalenceProof(dleq DLEQProof, X *ristretto.Element, Y *ristretto.Element, P *ristretto.Element, Q *ristretto.Element, transcript *core.Transcript) bool {

View File

@ -3,6 +3,7 @@ package privacypass
import ( import (
"crypto/hmac" "crypto/hmac"
"crypto/rand" "crypto/rand"
"encoding/json"
"fmt" "fmt"
"git.openprivacy.ca/cwtch.im/tapir/primitives/core" "git.openprivacy.ca/cwtch.im/tapir/primitives/core"
"git.openprivacy.ca/openprivacy/log" "git.openprivacy.ca/openprivacy/log"
@ -122,3 +123,16 @@ func UnblindSignedTokenBatch(tokens []*Token, blindedTokens []BlindedToken, sign
} }
return true 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,
})
}

View File

@ -9,7 +9,6 @@ import (
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor" torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
"git.openprivacy.ca/openprivacy/log" "git.openprivacy.ca/openprivacy/log"
"golang.org/x/crypto/ed25519" "golang.org/x/crypto/ed25519"
"io/ioutil"
"os" "os"
"runtime" "runtime"
"runtime/pprof" "runtime/pprof"
@ -69,7 +68,7 @@ func TestTapir(t *testing.T) {
torDataDir := "" torDataDir := ""
var err error 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") 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)) conn, _ := client.GetConnection(torProvider.GetTorV3Hostname(key))
log.Debugf("Client has Auth: %v", conn.HasCapability(applications.AuthCapability)) 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 // attempt to send a message that is too long
var long [8195]byte var long [8195]byte
err := conn.Send(long[:]) err := conn.Send(long[:])

View File

@ -8,7 +8,6 @@ import (
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor" torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
"git.openprivacy.ca/openprivacy/log" "git.openprivacy.ca/openprivacy/log"
"golang.org/x/crypto/ed25519" "golang.org/x/crypto/ed25519"
"io/ioutil"
"os" "os"
"runtime" "runtime"
"sync" "sync"
@ -30,7 +29,7 @@ func TestTapirMaliciousRemote(t *testing.T) {
torDataDir := "" torDataDir := ""
var err error 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") t.Fatalf("could not create data dir")
} }

View File

@ -16,16 +16,16 @@ func EDH(privateKey ed25519.PrivateKey, remotePublicKey ed25519.PublicKey) ([]by
var curve25519priv [32]byte var curve25519priv [32]byte
PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes) PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes)
curve25519pub, err := ed25519PublicKeyToCurve25519(remotePublicKey) remoteCurve25519pub, err := ed25519PublicKeyToCurve25519New(remotePublicKey)
if err == nil { if err != nil {
return nil, err return []byte{}, err
} }
secret, err := curve25519.X25519(curve25519priv[:], curve25519pub[:]) secret, err := curve25519.X25519(curve25519priv[:], remoteCurve25519pub[:])
return secret, err return secret, err
} }
// reproduced from https://github.com/FiloSottile/age/blob/main/agessh/agessh.go#L190 // reproduced from https://github.com/FiloSottile/age/blob/main/agessh/agessh.go#L190
func ed25519PublicKeyToCurve25519(pk ed25519.PublicKey) ([]byte, error) { func ed25519PublicKeyToCurve25519New(pk ed25519.PublicKey) ([]byte, error) {
// See https://blog.filippo.io/using-ed25519-keys-for-encryption and // See https://blog.filippo.io/using-ed25519-keys-for-encryption and
// https://pkg.go.dev/filippo.io/edwards25519#Point.BytesMontgomery. // https://pkg.go.dev/filippo.io/edwards25519#Point.BytesMontgomery.
p, err := new(edwards25519.Point).SetBytes(pk) p, err := new(edwards25519.Point).SetBytes(pk)