diff --git a/src/croc/croc.go b/src/croc/croc.go index e8d5801..b2c7f82 100644 --- a/src/croc/croc.go +++ b/src/croc/croc.go @@ -10,8 +10,7 @@ import ( "github.com/gorilla/websocket" "github.com/pion/webrtc/v2" - "github.com/schollz/croc/v7/src/compress" - "github.com/schollz/croc/v7/src/crypt" + "github.com/schollz/croc/v7/src/box" log "github.com/schollz/logger" "github.com/schollz/pake/v2" ) @@ -66,44 +65,6 @@ type WebsocketMessage struct { Payload string } - -// SendWebsocketMessage communicates using base64 -func (c *Client) SendWebsocketMessage(wsmsg WebsocketMessage, encrypt bool) (err error) { - var b []byte - if encrypt { - b, err = c.Bundle(wsmsg) - } else { - b, err = json.Marshal(wsmsg) - if err != nil { - log.Error(err) - return - } - } - bd := base64.StdEncoding.EncodeToString(b) - err = c.ws.WriteMessage(1, []byte(bd)) - return -} - -// ReceiveWebsocketMessage communicates using base64 -func (c *Client) ReceiveWebsocketMessage(decrypt bool) (wsmsg WebsocketMessage, err error) { - _, msg, err := c.ws.ReadMessage() - if err != nil { - log.Error(err) - return - } - b, err := base64.StdEncoding.DecodeString(string(msg)) - if decrypt { - err = c.Unbundle(b, &wsmsg) - if err != nil { - log.Error(err) - return - } - } else { - err = json.Unmarshal(b, &wsmsg) - } - return -} - // New establishes a new connection for transferring files between two instances. func New(ops Options) (c *Client, err error) { c = new(Client) @@ -123,176 +84,176 @@ func New(ops Options) (c *Client, err error) { return } - // initialize pake - if c.IsOfferer { - c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 0, elliptic.P521(), 1*time.Microsecond) - } else { - c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 1, elliptic.P521(), 1*time.Microsecond) - } - if err != nil { - return - } + // // initialize pake + // if c.IsOfferer { + // c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 0, elliptic.P521(), 1*time.Microsecond) + // } else { + // c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 1, elliptic.P521(), 1*time.Microsecond) + // } + // if err != nil { + // return + // } - if c.IsOfferer { - // offerer sends the first pake - c.SendWebsocketMessage(WebsocketMessage{ - Message: "pake", - Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()), - }, false) - } else { - // answerer receives the first pake - err = c.getPAKE(true) - if err != nil { - log.Error(err) - return - } - } + // if c.IsOfferer { + // // offerer sends the first pake + // c.SendWebsocketMessage(WebsocketMessage{ + // Message: "pake", + // Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()), + // }, false) + // } else { + // // answerer receives the first pake + // err = c.getPAKE(true) + // if err != nil { + // log.Error(err) + // return + // } + // } - // one more exchange to finish (offerer must send) - err = c.getPAKE(c.IsOfferer) - if err != nil { - log.Error(err) - return - } - log.Debug(c.Pake.SessionKey()) + // // one more exchange to finish (offerer must send) + // err = c.getPAKE(c.IsOfferer) + // if err != nil { + // log.Error(err) + // return + // } + // log.Debug(c.Pake.SessionKey()) - // generate the session key for encryption - pakeSessionKey, err := c.Pake.SessionKey() - if err != nil { - log.Error(err) - return - } - c.Key, err = crypt.New(pakeSessionKey, []byte(c.Options.SharedSecret)) - if err != nil { - log.Error(err) - return - } + // // generate the session key for encryption + // pakeSessionKey, err := c.Pake.SessionKey() + // if err != nil { + // log.Error(err) + // return + // } + // c.Key, err = crypt.New(pakeSessionKey, []byte(c.Options.SharedSecret)) + // if err != nil { + // log.Error(err) + // return + // } - // create webrtc connection - finished := make(chan error, 1) - c.rtc, err = c.CreateOfferer(finished) - if err != nil { - log.Error(err) - } + // // create webrtc connection + // finished := make(chan error, 1) + // c.rtc, err = c.CreateOfferer(finished) + // if err != nil { + // log.Error(err) + // } - offer, err := c.rtc.CreateOffer(nil) - if err != nil { - log.Error(err) - return - } - if c.IsOfferer { - // Now, create an offer - err = c.rtc.SetLocalDescription(offer) - if err != nil { - log.Error(err) - return - } + // offer, err := c.rtc.CreateOffer(nil) + // if err != nil { + // log.Error(err) + // return + // } + // if c.IsOfferer { + // // Now, create an offer + // err = c.rtc.SetLocalDescription(offer) + // if err != nil { + // log.Error(err) + // return + // } - // bundle it and send it over - var offerJSON []byte - offerJSON, err = json.Marshal(offer) - if err != nil { - log.Error(err) - } - err = c.SendWebsocketMessage( - WebsocketMessage{ - Message: "offer", - Payload: base64.StdEncoding.EncodeToString(offerJSON), - }, - true, - ) - if err != nil { - log.Error(err) - return - } + // // bundle it and send it over + // var offerJSON []byte + // offerJSON, err = json.Marshal(offer) + // if err != nil { + // log.Error(err) + // } + // err = c.SendWebsocketMessage( + // WebsocketMessage{ + // Message: "offer", + // Payload: base64.StdEncoding.EncodeToString(offerJSON), + // }, + // true, + // ) + // if err != nil { + // log.Error(err) + // return + // } - // wait for the answer - var wsmsg WebsocketMessage - wsmsg, err = c.ReceiveWebsocketMessage(true) + // // wait for the answer + // var wsmsg WebsocketMessage + // wsmsg, err = c.ReceiveWebsocketMessage(true) - var payload []byte - payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload) - err = setRemoteDescription(c.rtc, payload) - if err != nil { - log.Error(err) - return - } - } else { - // wait for the offer - var wsmsg WebsocketMessage - wsmsg, err = c.ReceiveWebsocketMessage(true) + // var payload []byte + // payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload) + // err = setRemoteDescription(c.rtc, payload) + // if err != nil { + // log.Error(err) + // return + // } + // } else { + // // wait for the offer + // var wsmsg WebsocketMessage + // wsmsg, err = c.ReceiveWebsocketMessage(true) - var payload []byte - payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload) - err = setRemoteDescription(c.rtc, payload) - if err != nil { - log.Error(err) - return - } + // var payload []byte + // payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload) + // err = setRemoteDescription(c.rtc, payload) + // if err != nil { + // log.Error(err) + // return + // } - var answer webrtc.SessionDescription - answer, err = c.rtc.CreateAnswer(nil) - if err != nil { - log.Error(err) - return - } - err = c.rtc.SetLocalDescription(answer) - if err != nil { - log.Error(err) - return - } + // var answer webrtc.SessionDescription + // answer, err = c.rtc.CreateAnswer(nil) + // if err != nil { + // log.Error(err) + // return + // } + // err = c.rtc.SetLocalDescription(answer) + // if err != nil { + // log.Error(err) + // return + // } - // bundle it and send it over - var answerJSON []byte - answerJSON, err = json.Marshal(answer) - if err != nil { - log.Error(err) - } - err = c.SendWebsocketMessage( - WebsocketMessage{ - Message: "answer", - Payload: base64.StdEncoding.EncodeToString(answerJSON), - }, - true, - ) - if err != nil { - log.Error(err) - return - } + // // bundle it and send it over + // var answerJSON []byte + // answerJSON, err = json.Marshal(answer) + // if err != nil { + // log.Error(err) + // } + // err = c.SendWebsocketMessage( + // WebsocketMessage{ + // Message: "answer", + // Payload: base64.StdEncoding.EncodeToString(answerJSON), + // }, + // true, + // ) + // if err != nil { + // log.Error(err) + // return + // } - } + // } - err = <-finished + // err = <-finished return } -func (c *Client) getPAKE(keepSending bool) (err error) { - // answerer receives the first pake - p, err := c.ReceiveWebsocketMessage(false) - if err != nil { - log.Error(err) - return - } - payload, err := base64.StdEncoding.DecodeString(p.Payload) - if err != nil { - log.Error(err) - return - } - log.Debugf("payload: %s", payload) - err = c.Pake.Update(payload) - if err != nil { - log.Error(err) - return - } - if keepSending { - // sends back PAKE bytes - err = c.SendWebsocketMessage(WebsocketMessage{ - Message: "pake", - Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()), - }, false) - } - return -} +// func (c *Client) getPAKE(keepSending bool) (err error) { +// // answerer receives the first pake +// p, err := c.ReceiveWebsocketMessage(false) +// if err != nil { +// log.Error(err) +// return +// } +// payload, err := base64.StdEncoding.DecodeString(p.Payload) +// if err != nil { +// log.Error(err) +// return +// } +// log.Debugf("payload: %s", payload) +// err = c.Pake.Update(payload) +// if err != nil { +// log.Error(err) +// return +// } +// if keepSending { +// // sends back PAKE bytes +// err = c.SendWebsocketMessage(WebsocketMessage{ +// Message: "pake", +// Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()), +// }, false) +// } +// return +// } // Send will send the specified file func (c *Client) Send(options TransferOptions) (err error) { @@ -315,25 +276,66 @@ func (c *Client) connectToRelay() (err error) { } log.Debugf("connected and sending first message") - c.SendWebsocketMessage(WebsocketMessage{ - Message: "offerer", - }, false) - wsmsg, err := c.ReceiveWebsocketMessage(false) + bundled, err := box.Bundle(WebsocketMessage{ + Message: "you are offerer", + }, c.Key) if err != nil { - log.Debug("read:", err) + log.Error(err) return } - log.Debugf("recv: %s", wsmsg) - if wsmsg.Message == "offerer" { - c.IsOfferer = true - c.ws.WriteJSON(WebsocketMessage{ - Message: "answerer", - }) - } else if wsmsg.Message == "answerer" { - c.IsOfferer = false - } else { - err = fmt.Errorf("got bad message: %+v", wsmsg) + err = c.ws.WriteMessage(1, []byte(bundled)) + if err != nil { log.Error(err) + return + } + + for { + var wsmsg, wsreply WebsocketMessage + var msg []byte + _, msg, err = c.ws.ReadMessage() + if err != nil { + log.Debug("read:", err) + return + } + err = box.Unbundle(string(msg), c.Key, &wsmsg) + log.Debugf("recv: %s", wsmsg.Message) + if wsmsg.Message == "you are offerer" { + c.IsOfferer = true + c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 0, elliptic.P521(), 1*time.Microsecond) + wsreply.Message = "you are answerer" + } else if wsmsg.Message == "you are answerer" { + c.IsOfferer = false + c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 1, elliptic.P521(), 1*time.Microsecond) + wsreply.Message = "pake1" + wsreply.Payload = base64.StdEncoding.EncodeToString(c.Pake.Bytes()) + } else if wsmsg.Message == "pake2" || wsmsg.Message == "pake3" { + var pakeBytes []byte + pakeBytes, err = base64.StdEncoding.DecodeString(wsreply.Payload) + if err != nil { + log.Error(err) + return + } + err = c.Pake.Update(pakeBytes) + if err != nil { + log.Error(err) + return + } + if wsmsg.Message == "pake2" { + wsreply.Message = "pake3" + wsreply.Payload = base64.StdEncoding.EncodeToString(c.Pake.Bytes()) + } + } else { + log.Debug("unknown") + } + if wsmsg.Message != "" { + var bundled string + bundled, err = box.Bundle(wsreply, c.Key) + err = c.ws.WriteMessage(1, []byte(bundled)) + if err != nil { + log.Error(err) + return + } + } } return } @@ -412,10 +414,10 @@ func (c *Client) CreateOfferer(finished chan<- error) (pc *webrtc.PeerConnection for { its++ - msg, _ := c.Bundle(WebsocketMessage{ + msg, _ := box.Bundle(WebsocketMessage{ Message: fmt.Sprintf("%d", its), - }) - err2 := sendData(msg) + }, c.Key) + err2 := sendData([]byte(msg)) if err2 != nil { finished <- err2 return @@ -439,7 +441,7 @@ func (c *Client) CreateOfferer(finished chan<- error) (pc *webrtc.PeerConnection // Register the OnMessage to handle incoming messages dc.OnMessage(func(dcMsg webrtc.DataChannelMessage) { var wsmsg WebsocketMessage - err := c.Unbundle(dcMsg.Data, &wsmsg) + err = box.Unbundle(string(dcMsg.Data), c.Key, &wsmsg) if err == nil { log.Debugf("wsmsg: %+v", wsmsg) } else {