mirror of https://github.com/schollz/croc.git
use age for tcp
This commit is contained in:
parent
9db87434a7
commit
c3c892f95d
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module github.com/schollz/croc/v9
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/age v1.0.0-rc.1 // indirect
|
filippo.io/age v1.0.0-rc.1
|
||||||
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
||||||
github.com/cespare/xxhash v1.1.0
|
github.com/cespare/xxhash v1.1.0
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||||
|
|
|
@ -86,7 +86,7 @@ func NewAge() (pubkey string, privkey string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncryptAge(pubkey string, data []byte) (encrypted []byte, err error) {
|
func EncryptAge(data []byte, pubkey string) (encrypted []byte, err error) {
|
||||||
recipient, err := age.ParseX25519Recipient(pubkey)
|
recipient, err := age.ParseX25519Recipient(pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -109,7 +109,7 @@ func EncryptAge(pubkey string, data []byte) (encrypted []byte, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecryptAge(privkey string, encrypted []byte) (data []byte, err error) {
|
func DecryptAge(encrypted []byte, privkey string) (data []byte, err error) {
|
||||||
identity, err := age.ParseX25519Identity(privkey)
|
identity, err := age.ParseX25519Identity(privkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
|
@ -103,3 +103,15 @@ func TestEncryptionChaCha(t *testing.T) {
|
||||||
_, _, err = NewArgon2([]byte(""), nil)
|
_, _, err = NewArgon2([]byte(""), nil)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncryptionAge(t *testing.T) {
|
||||||
|
pub, priv, err := NewAge()
|
||||||
|
fmt.Printf("key: %s\n", pub)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
msg := []byte("hello, world")
|
||||||
|
enc, err := EncryptAge(msg, pub)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
dec, err := DecryptAge(enc, priv)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, msg, dec)
|
||||||
|
}
|
||||||
|
|
141
src/tcp/tcp.go
141
src/tcp/tcp.go
|
@ -8,10 +8,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/schollz/logger"
|
|
||||||
"github.com/schollz/pake/v3"
|
|
||||||
|
|
||||||
"filippo.io/age"
|
"filippo.io/age"
|
||||||
|
log "github.com/schollz/logger"
|
||||||
|
|
||||||
"github.com/schollz/croc/v9/src/comm"
|
"github.com/schollz/croc/v9/src/comm"
|
||||||
"github.com/schollz/croc/v9/src/crypt"
|
"github.com/schollz/croc/v9/src/crypt"
|
||||||
"github.com/schollz/croc/v9/src/models"
|
"github.com/schollz/croc/v9/src/models"
|
||||||
|
@ -19,8 +18,8 @@ import (
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
port string
|
port string
|
||||||
privateKey string
|
keyPrivate string
|
||||||
publicKey string
|
keyPublic string
|
||||||
debugLevel string
|
debugLevel string
|
||||||
banner string
|
banner string
|
||||||
password string
|
password string
|
||||||
|
@ -43,9 +42,11 @@ var timeToRoomDeletion = 10 * time.Minute
|
||||||
var pingRoom = "pinglkasjdlfjsaldjf"
|
var pingRoom = "pinglkasjdlfjsaldjf"
|
||||||
|
|
||||||
// Run starts a tcp listener, run async
|
// Run starts a tcp listener, run async
|
||||||
func Run(debugLevel, port, password string, banner ...string) (err error) {
|
func Run(debugLevel, port, password string, keyPublic string, keyPrivate string, banner ...string) (err error) {
|
||||||
s := new(server)
|
s := new(server)
|
||||||
s.port = port
|
s.port = port
|
||||||
|
s.keyPrivate = keyPrivate
|
||||||
|
s.keyPublic = keyPublic
|
||||||
s.password = password
|
s.password = password
|
||||||
s.debugLevel = debugLevel
|
s.debugLevel = debugLevel
|
||||||
if len(banner) > 0 {
|
if len(banner) > 0 {
|
||||||
|
@ -154,68 +155,21 @@ func (s *server) run() (err error) {
|
||||||
var weakKey = []byte{1, 2, 3}
|
var weakKey = []byte{1, 2, 3}
|
||||||
|
|
||||||
func (s *server) clientCommunication(port string, c *comm.Comm) (room string, err error) {
|
func (s *server) clientCommunication(port string, c *comm.Comm) (room string, err error) {
|
||||||
identity, err := age.GenerateX25519Identity()
|
// get public key of the connecting client
|
||||||
|
retBytesEnc, err := c.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// send public key for encryption
|
retBytes, err := crypt.DecryptAge(retBytesEnc, s.keyPrivate)
|
||||||
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Abytes, err := c.Receive()
|
// check whether we have a valid public key from client
|
||||||
|
keyPublic := string(retBytes)
|
||||||
|
_, err := age.ParseX25519Recipient(keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if bytes.Equal(Abytes, []byte("ping")) {
|
|
||||||
room = pingRoom
|
|
||||||
c.Send([]byte("pong"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = B.Update(Abytes)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = c.Send(B.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongKey, err := B.SessionKey()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Debugf("strongkey: %x", strongKey)
|
|
||||||
|
|
||||||
// receive salt
|
|
||||||
salt, err := c.Receive()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongKeyForEncryption, _, err := crypt.New(strongKey, salt)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("waiting for password")
|
|
||||||
passwordBytesEnc, err := c.Receive()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
passwordBytes, err := crypt.Decrypt(passwordBytesEnc, strongKeyForEncryption)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(string(passwordBytes)) != s.password {
|
|
||||||
err = fmt.Errorf("bad password")
|
|
||||||
enc, _ := crypt.Decrypt([]byte(err.Error()), strongKeyForEncryption)
|
|
||||||
if err := c.Send(enc); err != nil {
|
|
||||||
return "", fmt.Errorf("send error: %w", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// send ok to tell client they are connected
|
// send ok to tell client they are connected
|
||||||
banner := s.banner
|
banner := s.banner
|
||||||
|
@ -223,7 +177,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
banner = "ok"
|
banner = "ok"
|
||||||
}
|
}
|
||||||
log.Debugf("sending '%s'", banner)
|
log.Debugf("sending '%s'", banner)
|
||||||
bSend, err := crypt.Encrypt([]byte(banner+"|||"+c.Connection().RemoteAddr().String()), strongKeyForEncryption)
|
bSend, err := crypt.EncryptAge([]byte(banner+"|||"+c.Connection().RemoteAddr().String()), keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -238,7 +192,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
roomBytes, err := crypt.Decrypt(enc, strongKeyForEncryption)
|
roomBytes, err := crypt.DecryptAge(enc, s.keyPrivate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -254,7 +208,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
s.rooms.Unlock()
|
s.rooms.Unlock()
|
||||||
// tell the client that they got the room
|
// tell the client that they got the room
|
||||||
|
|
||||||
bSend, err = crypt.Encrypt([]byte("ok"), strongKeyForEncryption)
|
bSend, err = crypt.EncryptAge([]byte("ok"), keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -269,7 +223,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
}
|
}
|
||||||
if s.rooms.rooms[room].full {
|
if s.rooms.rooms[room].full {
|
||||||
s.rooms.Unlock()
|
s.rooms.Unlock()
|
||||||
bSend, err = crypt.Encrypt([]byte("room full"), strongKeyForEncryption)
|
bSend, err = crypt.EncryptAge([]byte("room full"), keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -425,65 +379,40 @@ func ConnectToTCPServer(address, password, room string, timelimit ...time.Durati
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get PAKE connection with server to establish strong key to transfer info
|
// generate ephermeral key
|
||||||
A, err := pake.InitCurve(weakKey, 0, "siec")
|
keyPublic, keyPrivate, err := crypt.NewAge()
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = c.Send(A.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Bbytes, err := c.Receive()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = A.Update(Bbytes)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongKey, err := A.SessionKey()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Debugf("strong key: %x", strongKey)
|
|
||||||
|
|
||||||
strongKeyForEncryption, salt, err := crypt.New(strongKey, nil)
|
// send epheremal public key, encrypted using the server's public key
|
||||||
if err != nil {
|
foo := strings.Split(password, "--")
|
||||||
return
|
keyPublicRelay = foo[1]
|
||||||
}
|
password = foo[2]
|
||||||
// send salt
|
|
||||||
err = c.Send(salt)
|
sendBytesEnc, err := crypt.EncryptAge([]byte(keyPublic), keyPublicRelay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("sending password")
|
err = c.Send(sendBytesEnc)
|
||||||
bSend, err := crypt.Encrypt([]byte(password), strongKeyForEncryption)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = c.Send(bSend)
|
retBytesEnc, err := c.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("waiting for first ok")
|
retBytes, err := crypt.DecryptAge(retBytesEnc, keyPrivate)
|
||||||
enc, err := c.Receive()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data, err := crypt.Decrypt(enc, strongKeyForEncryption)
|
if !strings.Contains(string(retBytes), "|||") {
|
||||||
if err != nil {
|
err = fmt.Errorf("bad response: %s", string(retBytes))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(string(data), "|||") {
|
banner = strings.Split(string(retBytes), "|||")[0]
|
||||||
err = fmt.Errorf("bad response: %s", string(data))
|
ipaddr = strings.Split(string(retBytes), "|||")[1]
|
||||||
return
|
|
||||||
}
|
|
||||||
banner = strings.Split(string(data), "|||")[0]
|
|
||||||
ipaddr = strings.Split(string(data), "|||")[1]
|
|
||||||
log.Debug("sending room")
|
log.Debug("sending room")
|
||||||
bSend, err = crypt.Encrypt([]byte(room), strongKeyForEncryption)
|
bSend, err = crypt.EncryptAge([]byte(room), keyPublicRelay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -496,7 +425,7 @@ func ConnectToTCPServer(address, password, room string, timelimit ...time.Durati
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data, err = crypt.Decrypt(enc, strongKeyForEncryption)
|
data, err = crypt.DecryptAge(enc, keyPrivate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue