diff --git a/go.mod b/go.mod index 7a32ccd9..2dbdf612 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/schollz/croc/v9 go 1.13 require ( + filippo.io/age v1.0.0-rc.1 // indirect github.com/OneOfOne/xxhash v1.2.5 // indirect github.com/cespare/xxhash v1.1.0 github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index 16af15b2..bc8b68fe 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +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= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= @@ -61,6 +63,7 @@ github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094/go.mod h1:KL9+ubr1JZ github.com/twmb/murmur3 v1.1.5 h1:i9OLS9fkuLzBXjt6dptlAEyk58fJsSTXbRg3SgVyqgk= github.com/twmb/murmur3 v1.1.5/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc h1:+q90ECDSAQirdykUN6sPEiBXBsp8Csjcca8Oy7bgLTA= golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= diff --git a/src/crypt/crypt.go b/src/crypt/crypt.go index 6ae2a1c3..b1b431c1 100644 --- a/src/crypt/crypt.go +++ b/src/crypt/crypt.go @@ -1,13 +1,16 @@ package crypt import ( + "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/sha256" "fmt" + "io" "log" + "filippo.io/age" "golang.org/x/crypto/argon2" "golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/pbkdf2" @@ -73,6 +76,60 @@ func Decrypt(encrypted []byte, key []byte) (plaintext []byte, err error) { return } +func NewAge() (pubkey string, privkey string, err error) { + identity, err := age.GenerateX25519Identity() + if err != nil { + return + } + pubkey = identity.Recipient().String() + privkey = identity.String() + return +} + +func EncryptAge(pubkey string, data []byte) (encrypted []byte, err error) { + recipient, err := age.ParseX25519Recipient(pubkey) + if err != nil { + return + } + + out := &bytes.Buffer{} + w, err := age.Encrypt(out, recipient) + if err != nil { + return + } + _, err = w.Write(data) + if err != nil { + return + } + err = w.Close() + if err != nil { + return + } + encrypted = out.Bytes() + return +} + +func DecryptAge(privkey string, encrypted []byte) (data []byte, err error) { + identity, err := age.ParseX25519Identity(privkey) + if err != nil { + return + } + + r, err := age.Decrypt(bytes.NewReader(encrypted), identity) + if err != nil { + return + } + + out := &bytes.Buffer{} + _, err = io.Copy(out, r) + if err != nil { + return + } + + data = out.Bytes() + return +} + // NewArgon2 generates a new key based on a passphrase and salt // using argon2 // https://pkg.go.dev/golang.org/x/crypto/argon2 diff --git a/src/tcp/tcp.go b/src/tcp/tcp.go index 96b4145f..a578b148 100644 --- a/src/tcp/tcp.go +++ b/src/tcp/tcp.go @@ -11,6 +11,7 @@ import ( log "github.com/schollz/logger" "github.com/schollz/pake/v3" + "filippo.io/age" "github.com/schollz/croc/v9/src/comm" "github.com/schollz/croc/v9/src/crypt" "github.com/schollz/croc/v9/src/models" @@ -18,6 +19,8 @@ import ( type server struct { port string + privateKey string + publicKey string debugLevel string banner string password string @@ -151,6 +154,13 @@ func (s *server) run() (err error) { var weakKey = []byte{1, 2, 3} func (s *server) clientCommunication(port string, c *comm.Comm) (room string, err error) { + identity, err := age.GenerateX25519Identity() + if err != nil { + return + } + // send public key for encryption + c.Send([]byte(identity.Recipient().String())) + // establish secure password with PAKE for communication with relay B, err := pake.InitCurve(weakKey, 1, "siec") if err != nil {