diff --git a/browser/assets2/tun1.wasm b/browser/assets2/tun1.wasm new file mode 100755 index 000000000..ca209d6a4 Binary files /dev/null and b/browser/assets2/tun1.wasm differ diff --git a/signal/client/client.go b/signal/client/client.go index 741a2089f..2cfbd70e5 100644 --- a/signal/client/client.go +++ b/signal/client/client.go @@ -2,6 +2,7 @@ package client import ( "fmt" + "github.com/wiretrustee/wiretrustee/encryption" "github.com/wiretrustee/wiretrustee/signal/proto" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "strings" @@ -17,6 +18,46 @@ type Client interface { WaitConnected() } +// decryptMessage decrypts the body of the msg using Wireguard private key and Remote peer's public key +func decryptMessage(msg *proto.EncryptedMessage, wgPrivateKey wgtypes.Key) (*proto.Message, error) { + remoteKey, err := wgtypes.ParseKey(msg.GetKey()) + if err != nil { + return nil, err + } + + body := &proto.Body{} + err = encryption.DecryptMessage(remoteKey, wgPrivateKey, msg.GetBody(), body) + if err != nil { + return nil, err + } + + return &proto.Message{ + Key: msg.Key, + RemoteKey: msg.RemoteKey, + Body: body, + }, nil +} + +// encryptMessage encrypts the body of the msg using Wireguard private key and Remote peer's public key +func encryptMessage(msg *proto.Message, wgPrivateKey wgtypes.Key) (*proto.EncryptedMessage, error) { + + remoteKey, err := wgtypes.ParseKey(msg.RemoteKey) + if err != nil { + return nil, err + } + + encryptedBody, err := encryption.EncryptMessage(remoteKey, wgPrivateKey, msg.Body) + if err != nil { + return nil, err + } + + return &proto.EncryptedMessage{ + Key: msg.GetKey(), + RemoteKey: msg.GetRemoteKey(), + Body: encryptedBody, + }, nil +} + // UnMarshalCredential parses the credentials from the message and returns a Credential instance func UnMarshalCredential(msg *proto.Message) (*Credential, error) { diff --git a/signal/client/grpc_client.go b/signal/client/grpc_client.go index dcecc37a4..25d818bff 100644 --- a/signal/client/grpc_client.go +++ b/signal/client/grpc_client.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/cenkalti/backoff/v4" log "github.com/sirupsen/logrus" - "github.com/wiretrustee/wiretrustee/encryption" "github.com/wiretrustee/wiretrustee/signal/proto" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "google.golang.org/grpc" @@ -58,7 +57,7 @@ func NewClient(ctx context.Context, addr string, key wgtypes.Key, tlsEnabled boo })) if err != nil { - log.Errorf("failed to connect to the signalling server %v", err) + log.Errorf("failed to connect to the Signal gRPC server %v", err) return nil, err } @@ -175,50 +174,10 @@ func (c *GrpcClient) SendToStream(msg *proto.EncryptedMessage) error { return nil } -// decryptMessage decrypts the body of the msg using Wireguard private key and Remote peer's public key -func (c *GrpcClient) decryptMessage(msg *proto.EncryptedMessage) (*proto.Message, error) { - remoteKey, err := wgtypes.ParseKey(msg.GetKey()) - if err != nil { - return nil, err - } - - body := &proto.Body{} - err = encryption.DecryptMessage(remoteKey, c.key, msg.GetBody(), body) - if err != nil { - return nil, err - } - - return &proto.Message{ - Key: msg.Key, - RemoteKey: msg.RemoteKey, - Body: body, - }, nil -} - -// encryptMessage encrypts the body of the msg using Wireguard private key and Remote peer's public key -func (c *GrpcClient) encryptMessage(msg *proto.Message) (*proto.EncryptedMessage, error) { - - remoteKey, err := wgtypes.ParseKey(msg.RemoteKey) - if err != nil { - return nil, err - } - - encryptedBody, err := encryption.EncryptMessage(remoteKey, c.key, msg.Body) - if err != nil { - return nil, err - } - - return &proto.EncryptedMessage{ - Key: msg.GetKey(), - RemoteKey: msg.GetRemoteKey(), - Body: encryptedBody, - }, nil -} - // Send sends a message to the remote Peer through the Signal Exchange. func (c *GrpcClient) Send(msg *proto.Message) error { - encryptedMessage, err := c.encryptMessage(msg) + encryptedMessage, err := encryptMessage(msg, c.key) if err != nil { return err } @@ -251,7 +210,7 @@ func (c *GrpcClient) receive(stream proto.SignalExchange_ConnectStreamClient, } log.Debugf("received a new message from Peer [fingerprint: %s]", msg.Key) - decryptedMessage, err := c.decryptMessage(msg) + decryptedMessage, err := decryptMessage(msg, c.key) if err != nil { log.Errorf("failed decrypting message of Peer [key: %s] error: [%s]", msg.Key, err.Error()) } diff --git a/signal/client/ws_client.go b/signal/client/ws_client.go index e1371f2be..40bcad0b3 100644 --- a/signal/client/ws_client.go +++ b/signal/client/ws_client.go @@ -2,35 +2,97 @@ package client import ( "context" + "encoding/base64" + pb "github.com/golang/protobuf/proto" + log "github.com/sirupsen/logrus" "github.com/wiretrustee/wiretrustee/signal/proto" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "nhooyr.io/websocket" + "time" ) //WebsocketClient is a Signal server websocket client (alternative to the original gRPC Client) type WebsocketClient struct { - key wgtypes.Key - ctx context.Context + key wgtypes.Key + ctx context.Context + conn *websocket.Conn } -func NewWebsocketClient(ctx context.Context, addr string, wgPrivateKey wgtypes.Key) (*WebsocketClient, error) { +func NewWebsocketClient(ctx context.Context, endpoint string, wgPrivateKey wgtypes.Key) (*WebsocketClient, error) { + + sigCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + // generate peer identifier from our public key and base64 encode it because it will be transferred via URL param + peerId := base64.URLEncoding.EncodeToString([]byte(wgPrivateKey.PublicKey().String())) + conn, res, err := websocket.Dial(sigCtx, endpoint+"?id="+peerId, &websocket.DialOptions{}) + if err != nil { + log.Errorf("failed to connect to the Signal Websocket server %v - %v", err, res) + return nil, err + } + return &WebsocketClient{ - key: wgPrivateKey, - ctx: ctx, + key: wgPrivateKey, + ctx: ctx, + conn: conn, }, nil } func (c *WebsocketClient) Close() error { - return nil + return c.conn.Close(websocket.StatusNormalClosure, "close") } func (c *WebsocketClient) Receive(msgHandler func(msg *proto.Message) error) { + for { + _, byteMsg, err := c.conn.Read(c.ctx) + if err != nil { + log.Errorf("failed reading message from Signal Websocket %v", err) + continue + } + encryptedMsg := &proto.EncryptedMessage{} + err = pb.Unmarshal(byteMsg, encryptedMsg) + if err != nil { + log.Errorf("failed unmarshalling message from Signal Websocket %v", err) + continue + } + + remotePubKey := encryptedMsg.Key + + log.Debugf("received a new message from Peer %s received via Websocket", remotePubKey) + + decryptedMsg, err := decryptMessage(encryptedMsg, c.key) + if err != nil { + log.Errorf("failed decrypting a message from peer %s received via Websocket %v", remotePubKey, err) + } + + err = msgHandler(decryptedMsg) + if err != nil { + log.Errorf("error while handling message from peer %s %v", remotePubKey, err) + //todo send something?? + } + } } func (c *WebsocketClient) SendToStream(msg *proto.EncryptedMessage) error { - return nil + + bytesMsg, err := pb.Marshal(msg) + if err != nil { + log.Errorf("failed marshalling message %v", err) + return err + } + + return c.conn.Write(c.ctx, websocket.MessageBinary, bytesMsg) } + func (c *WebsocketClient) Send(msg *proto.Message) error { - return nil + + encryptedMessage, err := encryptMessage(msg, c.key) + if err != nil { + return err + } + + return c.SendToStream(encryptedMessage) + } func (c *WebsocketClient) WaitConnected() { diff --git a/signal/peer/peer.go b/signal/peer/peer.go index df60ad95d..c22daeda8 100644 --- a/signal/peer/peer.go +++ b/signal/peer/peer.go @@ -1,6 +1,7 @@ package peer import ( + pb "github.com/golang/protobuf/proto" "github.com/gorilla/websocket" log "github.com/sirupsen/logrus" "github.com/wiretrustee/wiretrustee/signal/proto" @@ -22,8 +23,11 @@ func NewWebsocketChannel(conn *websocket.Conn) *WebsocketChannel { } func (c *WebsocketChannel) Send(msg *proto.EncryptedMessage) error { - //todo - return nil + b, err := pb.Marshal(msg) + if err != nil { + return err + } + return c.conn.WriteMessage(websocket.BinaryMessage, b) } // Peer representation of a connected Peer