diff --git a/libgm/binary/protoUtil.go b/libgm/binary/emojitype.go similarity index 72% rename from libgm/binary/protoUtil.go rename to libgm/binary/emojitype.go index a0d31d7..517ff0b 100644 --- a/libgm/binary/protoUtil.go +++ b/libgm/binary/emojitype.go @@ -1,27 +1,5 @@ package binary -import ( - "fmt" - - "google.golang.org/protobuf/proto" -) - -func EncodeProtoMessage(message proto.Message) ([]byte, error) { - data, err := proto.Marshal(message) - if err != nil { - return nil, fmt.Errorf("failed to encode proto message: %v", err) - } - return data, nil -} - -func DecodeProtoMessage(data []byte, message proto.Message) error { - err := proto.Unmarshal(data, message) - if err != nil { - return fmt.Errorf("failed to decode proto message: %v", err) - } - return nil -} - func (et EmojiType) Unicode() string { switch et { case EmojiType_LIKE: diff --git a/libgm/client.go b/libgm/client.go index 35fdd10..7ab064a 100644 --- a/libgm/client.go +++ b/libgm/client.go @@ -11,6 +11,7 @@ import ( "time" "github.com/rs/zerolog" + "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-gmessages/libgm/binary" "go.mau.fi/mautrix-gmessages/libgm/crypto" @@ -208,7 +209,7 @@ func (c *Client) setApiMethods() { func (c *Client) DownloadMedia(mediaID string, key []byte) ([]byte, error) { reqId := util.RandomUUIDv4() - download_metadata := &binary.UploadImagePayload{ + downloadMetadata := &binary.UploadImagePayload{ MetaData: &binary.ImageMetaData{ ImageID: mediaID, Encrypted: true, @@ -219,16 +220,16 @@ func (c *Client) DownloadMedia(mediaID string, key []byte) ([]byte, error) { ConfigVersion: payload.ConfigMessage, }, } - download_metadata_bytes, err2 := binary.EncodeProtoMessage(download_metadata) + downloadMetadataBytes, err2 := proto.Marshal(downloadMetadata) if err2 != nil { return nil, err2 } - download_metadata_b64 := base64.StdEncoding.EncodeToString(download_metadata_bytes) + downloadMetadataEncoded := base64.StdEncoding.EncodeToString(downloadMetadataBytes) req, err := http.NewRequest("GET", util.UPLOAD_MEDIA, nil) if err != nil { return nil, err } - util.BuildUploadHeaders(req, download_metadata_b64) + util.BuildUploadHeaders(req, downloadMetadataEncoded) res, reqErr := c.http.Do(req) if reqErr != nil { return nil, reqErr diff --git a/libgm/crypto/cryptor.go b/libgm/crypto/cryptor.go index da071f7..e4f28cb 100644 --- a/libgm/crypto/cryptor.go +++ b/libgm/crypto/cryptor.go @@ -8,10 +8,6 @@ import ( "crypto/sha256" "errors" "io" - - "google.golang.org/protobuf/proto" - - "go.mau.fi/mautrix-gmessages/libgm/binary" ) type Cryptor struct { @@ -87,17 +83,3 @@ func (c *Cryptor) Decrypt(encryptedData []byte) ([]byte, error) { return encryptedDataWithoutHMAC, nil } - -func (c *Cryptor) EncodeAndEncryptData(message proto.Message) ([]byte, error) { - encodedData, encodeErr := binary.EncodeProtoMessage(message) - if encodeErr != nil { - return nil, encodeErr - } - - encryptedData, encryptErr := c.Encrypt(encodedData) - if encryptErr != nil { - return nil, encryptErr - } - - return encryptedData, nil -} diff --git a/libgm/crypto/decode.go b/libgm/crypto/decode.go deleted file mode 100644 index 519433a..0000000 --- a/libgm/crypto/decode.go +++ /dev/null @@ -1,21 +0,0 @@ -package crypto - -import ( - "encoding/base64" - - "google.golang.org/protobuf/proto" - - "go.mau.fi/mautrix-gmessages/libgm/binary" -) - -func DecodeAndEncodeB64(data string, msg proto.Message) error { - decodedBytes, err := base64.StdEncoding.DecodeString(data) - if err != nil { - return err - } - err = binary.DecodeProtoMessage(decodedBytes, msg) - if err != nil { - return err - } - return nil -} diff --git a/libgm/crypto/ECDSA.go b/libgm/crypto/ecdsa.go similarity index 85% rename from libgm/crypto/ECDSA.go rename to libgm/crypto/ecdsa.go index ea372cb..79ceeeb 100644 --- a/libgm/crypto/ECDSA.go +++ b/libgm/crypto/ecdsa.go @@ -4,7 +4,9 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" + "crypto/sha256" "encoding/base64" + "fmt" "math/big" ) @@ -70,6 +72,17 @@ func (t *JWK) MarshalPubKey() ([]byte, error) { return elliptic.Marshal(pubKey.Curve, pubKey.X, pubKey.Y), nil } +func (t *JWK) SignRequest(requestID string, timestamp int64) ([]byte, error) { + signBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%d", requestID, timestamp))) + + privKey, privErr := t.GetPrivateKey() + if privErr != nil { + return nil, privErr + } + + return ecdsa.SignASN1(rand.Reader, privKey, signBytes[:]) +} + // GenerateECDSAKey generates a new ECDSA private key with P-256 curve func GenerateECDSAKey() (*JWK, error) { privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) diff --git a/libgm/crypto/encode.go b/libgm/crypto/encode.go index 2be921a..0b1591f 100644 --- a/libgm/crypto/encode.go +++ b/libgm/crypto/encode.go @@ -1,13 +1,5 @@ package crypto -import ( - "encoding/base64" - - "google.golang.org/protobuf/proto" - - "go.mau.fi/mautrix-gmessages/libgm/binary" -) - var SequenceOne = []int{1, 2, 840, 10045, 2, 1} var SequenceTwo = []int{1, 2, 840, 10045, 3, 1, 7} @@ -51,12 +43,3 @@ func AppendByteSequence(byteArr1 []byte, byteArr2 []byte, uncompressedPublicKey copiedByteArray = HelperAppendBytes(copiedByteArray, 0) return copiedByteArray } - -func EncodeProtoB64(message proto.Message) (string, error) { - protoBytes, protoErr := binary.EncodeProtoMessage(message) - if protoErr != nil { - return "", protoErr - } - encodedStr := base64.StdEncoding.EncodeToString(protoBytes) - return encodedStr, nil -} diff --git a/libgm/crypto/signer.go b/libgm/crypto/signer.go deleted file mode 100644 index 0ced517..0000000 --- a/libgm/crypto/signer.go +++ /dev/null @@ -1,19 +0,0 @@ -package crypto - -import ( - "crypto/ecdsa" - "crypto/rand" - "crypto/sha256" - "fmt" -) - -func (t *JWK) SignRequest(requestID string, timestamp int64) ([]byte, error) { - signBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%d", requestID, timestamp))) - - privKey, privErr := t.GetPrivateKey() - if privErr != nil { - return nil, privErr - } - - return ecdsa.SignASN1(rand.Reader, privKey, signBytes[:]) -} diff --git a/libgm/media_processor.go b/libgm/media_processor.go index 426edb4..c0bff6e 100644 --- a/libgm/media_processor.go +++ b/libgm/media_processor.go @@ -2,13 +2,15 @@ package libgm import ( "bytes" + "encoding/base64" "errors" "io" "net/http" "strconv" + "google.golang.org/protobuf/proto" + "go.mau.fi/mautrix-gmessages/libgm/binary" - "go.mau.fi/mautrix-gmessages/libgm/crypto" "go.mau.fi/mautrix-gmessages/libgm/payload" "go.mau.fi/mautrix-gmessages/libgm/util" ) @@ -58,7 +60,7 @@ func (c *Client) FinalizeUploadMedia(upload *StartGoogleUpload) (*MediaUpload, e defer res.Body.Close() rHeaders := res.Header - googleResponse, err3 := io.ReadAll(res.Body) + googleResponse, err3 := io.ReadAll(base64.NewDecoder(base64.StdEncoding, res.Body)) if err3 != nil { return nil, err3 } @@ -67,7 +69,7 @@ func (c *Client) FinalizeUploadMedia(upload *StartGoogleUpload) (*MediaUpload, e c.Logger.Debug().Str("upload_status", uploadStatus).Msg("Upload complete") mediaIDs := &binary.UploadMediaResponse{} - err3 = crypto.DecodeAndEncodeB64(string(googleResponse), mediaIDs) + err3 = proto.Unmarshal(googleResponse, mediaIDs) if err3 != nil { return nil, err3 } @@ -135,10 +137,11 @@ func (c *Client) buildStartUploadPayload() (string, error) { Mobile: c.authData.DevicePair.Mobile, } - protoDataEncoded, protoEncodeErr := crypto.EncodeProtoB64(protoData) - if protoEncodeErr != nil { - return "", protoEncodeErr + protoDataBytes, err := proto.Marshal(protoData) + if err != nil { + return "", err } + protoDataEncoded := base64.StdEncoding.EncodeToString(protoDataBytes) return protoDataEncoded, nil } diff --git a/libgm/pair.go b/libgm/pair.go index b285815..bb57fa1 100644 --- a/libgm/pair.go +++ b/libgm/pair.go @@ -4,6 +4,8 @@ import ( "io" "time" + "google.golang.org/protobuf/proto" + "go.mau.fi/mautrix-gmessages/libgm/binary" "go.mau.fi/mautrix-gmessages/libgm/crypto" "go.mau.fi/mautrix-gmessages/libgm/events" @@ -59,7 +61,7 @@ func (p *Pairer) RegisterPhoneRelay() (*binary.RegisterPhoneRelayResponse, error } relayResponse.Body.Close() res := &binary.RegisterPhoneRelayResponse{} - err3 := binary.DecodeProtoMessage(responseBody, res) + err3 := proto.Unmarshal(responseBody, res) if err3 != nil { return nil, err3 } @@ -105,7 +107,7 @@ func (p *Pairer) RefreshPhoneRelay() { } p.client.Logger.Debug().Any("responseLength", len(responseBody)).Msg("Response Body Length") res := &binary.RefreshPhoneRelayResponse{} - err3 := binary.DecodeProtoMessage(responseBody, res) + err3 := proto.Unmarshal(responseBody, res) if err3 != nil { p.client.Logger.Err(err3) } @@ -138,7 +140,7 @@ func (c *Client) GetWebEncryptionKey() (*binary.WebEncryptionKeyResponse, error) } //p.client.Logger.Debug().Any("responseLength", len(responseBody)).Any("raw", responseBody).Msg("Response Body Length") parsedResponse := &binary.WebEncryptionKeyResponse{} - err2 = binary.DecodeProtoMessage(responseBody, parsedResponse) + err2 = proto.Unmarshal(responseBody, parsedResponse) if err2 != nil { c.Logger.Err(err2).Msg("Parse webkeyresponse into proto struct error") return nil, err2 diff --git a/libgm/payload/getWebEncryptionKey.go b/libgm/payload/getWebEncryptionKey.go index 81afaaf..56210f4 100644 --- a/libgm/payload/getWebEncryptionKey.go +++ b/libgm/payload/getWebEncryptionKey.go @@ -1,6 +1,8 @@ package payload import ( + "google.golang.org/protobuf/proto" + "go.mau.fi/mautrix-gmessages/libgm/binary" "go.mau.fi/mautrix-gmessages/libgm/util" ) @@ -14,7 +16,7 @@ func GetWebEncryptionKey(WebPairKey []byte) ([]byte, *binary.AuthenticationConta ConfigVersion: ConfigMessage, }, } - encodedPayload, err2 := binary.EncodeProtoMessage(payload) + encodedPayload, err2 := proto.Marshal(payload) if err2 != nil { return nil, payload, err2 } diff --git a/libgm/payload/refreshPhoneRelay.go b/libgm/payload/refreshPhoneRelay.go index 09de467..bf795c3 100644 --- a/libgm/payload/refreshPhoneRelay.go +++ b/libgm/payload/refreshPhoneRelay.go @@ -1,6 +1,8 @@ package payload import ( + "google.golang.org/protobuf/proto" + "go.mau.fi/mautrix-gmessages/libgm/binary" "go.mau.fi/mautrix-gmessages/libgm/util" ) @@ -14,7 +16,7 @@ func RefreshPhoneRelay(rpcKey []byte) ([]byte, *binary.AuthenticationContainer, ConfigVersion: ConfigMessage, }, } - encodedPayload, err2 := binary.EncodeProtoMessage(payload) + encodedPayload, err2 := proto.Marshal(payload) if err2 != nil { return nil, payload, err2 } diff --git a/libgm/payload/registerPhoneRelay.go b/libgm/payload/registerPhoneRelay.go index 63bdd95..11efb30 100644 --- a/libgm/payload/registerPhoneRelay.go +++ b/libgm/payload/registerPhoneRelay.go @@ -1,6 +1,8 @@ package payload import ( + "google.golang.org/protobuf/proto" + "go.mau.fi/mautrix-gmessages/libgm/binary" "go.mau.fi/mautrix-gmessages/libgm/crypto" "go.mau.fi/mautrix-gmessages/libgm/util" @@ -30,7 +32,7 @@ func RegisterPhoneRelay(jwk *crypto.JWK) ([]byte, *binary.AuthenticationContaine }, }, } - encoded, err4 := binary.EncodeProtoMessage(payloadData) + encoded, err4 := proto.Marshal(payloadData) if err4 != nil { return nil, payloadData, err4 } diff --git a/libgm/payload/sendMessage.go b/libgm/payload/sendMessage.go index f822ebf..ef70fb2 100644 --- a/libgm/payload/sendMessage.go +++ b/libgm/payload/sendMessage.go @@ -92,9 +92,15 @@ func (sm *SendMessageBuilder) SetTTL(ttl int64) *SendMessageBuilder { } func (sm *SendMessageBuilder) SetEncryptedProtoMessage(message proto.Message, cryptor *crypto.Cryptor) *SendMessageBuilder { - encryptedBytes, encryptErr := cryptor.EncodeAndEncryptData(message) - if encryptErr != nil { - sm.err = encryptErr + plaintextBytes, err := proto.Marshal(message) + if err != nil { + sm.err = err + return sm + } + + encryptedBytes, err := cryptor.Encrypt(plaintextBytes) + if err != nil { + sm.err = err return sm } diff --git a/libgm/pblite/internal.go b/libgm/pblite/internal.go index e2d41e4..7592780 100644 --- a/libgm/pblite/internal.go +++ b/libgm/pblite/internal.go @@ -44,14 +44,14 @@ func DecryptInternalMessage(internalMessage *binary.InternalMessage, cryptor *cr switch internalMessage.Data.BugleRoute { case binary.BugleRoute_PairEvent: decodedData := &binary.PairEvents{} - decodeErr := binary.DecodeProtoMessage(internalMessage.Data.ProtobufData, decodedData) + decodeErr := proto.Unmarshal(internalMessage.Data.ProtobufData, decodedData) if decodeErr != nil { return nil, decodeErr } resp = newResponseFromPairEvent(internalMessage.GetData(), decodedData) case binary.BugleRoute_DataEvent: internalRequestData := &binary.InternalRequestData{} - decodeErr := binary.DecodeProtoMessage(internalMessage.Data.ProtobufData, internalRequestData) + decodeErr := proto.Unmarshal(internalMessage.Data.ProtobufData, internalRequestData) if decodeErr != nil { return nil, decodeErr }