diff --git a/bindings/broadcast.go b/bindings/broadcast.go deleted file mode 100644 index adcae331543392ab5d8023d3b9c1c026beacaba7..0000000000000000000000000000000000000000 --- a/bindings/broadcast.go +++ /dev/null @@ -1,216 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2022 xx foundation // -// // -// Use of this source code is governed by a license that can be found in the // -// LICENSE file. // -//////////////////////////////////////////////////////////////////////////////// - -package bindings - -import ( - "encoding/json" - "github.com/pkg/errors" - "gitlab.com/elixxir/client/broadcast" - "gitlab.com/elixxir/client/cmix" - "gitlab.com/elixxir/client/cmix/identity/receptionID" - "gitlab.com/elixxir/client/cmix/rounds" - cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" - "gitlab.com/xx_network/crypto/signature/rsa" - "gitlab.com/xx_network/primitives/id/ephemeral" -) - -// Channel is a bindings-level struct encapsulating the broadcast.Channel client -// object. -type Channel struct { - ch broadcast.Channel -} - -// ChannelDef is the bindings representation of an elixxir/crypto -// broadcast.Channel object. -// -// Example JSON: -// { -// "Name": "My broadcast channel", -// "Description": "A broadcast channel for me to test things", -// "Salt": "gpUqW7N22sffMXsvPLE7BA==", -// "PubKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1DZ0NJUUN2YkZVckJKRFpqT3Y0Y0MvUHZZdXNvQkFtUTFkb3Znb044aHRuUjA2T3F3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" -// } -type ChannelDef struct { - Name string - Description string - Salt []byte - PubKey []byte -} - -// BroadcastMessage is the bindings representation of a broadcast message. -// -// BroadcastMessage Example JSON: -// { -// "RoundID":42, -// "EphID":[0,0,0,0,0,0,24,61], -// "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true", -// "Payload":"SGVsbG8sIGJyb2FkY2FzdCBmcmllbmRzIQ==" -// } -type BroadcastMessage struct { - BroadcastReport - Payload []byte -} - -// BroadcastReport is the bindings representation of the info on how a broadcast -// message was sent -// -// BroadcastReport Example JSON: -// { -// "Rounds": [25, 26, 29], -// "EphID":[0,0,0,0,0,0,24,61], -// "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true" -// } -type BroadcastReport struct { - RoundsList - RoundURL string - EphID ephemeral.Id -} - -// BroadcastListener is the public function type bindings can use to listen for -// broadcast messages. -// -// Parameters: -// - []byte - the JSON marshalled bytes of the BroadcastMessage object, which -// can be passed into WaitForRoundResult to see if the broadcast succeeded. -type BroadcastListener interface { - Callback([]byte, error) -} - -// NewBroadcastChannel creates a bindings-layer broadcast channel and starts -// listening for new messages. -// -// Parameters: -// - cmixId - internal ID of cmix -// - channelDefinition - JSON marshalled ChannelDef object -func NewBroadcastChannel(cmixId int, channelDefinition []byte) (*Channel, error) { - c, err := cmixTrackerSingleton.get(cmixId) - if err != nil { - return nil, err - } - - def := &ChannelDef{} - err = json.Unmarshal(channelDefinition, def) - if err != nil { - return nil, errors.WithMessage(err, "Failed to unmarshal underlying channel definition") - } - - channelID, err := cryptoBroadcast.NewChannelID(def.Name, def.Description, def.Salt, def.PubKey) - if err != nil { - return nil, errors.WithMessage(err, "Failed to generate channel ID") - } - chanPubLoaded, err := rsa.LoadPublicKeyFromPem(def.PubKey) - if err != nil { - return nil, errors.WithMessage(err, "Failed to load public key") - } - - ch, err := broadcast.NewBroadcastChannel(&cryptoBroadcast.Channel{ - ReceptionID: channelID, - Name: def.Name, - Description: def.Description, - Salt: def.Salt, - RsaPubKey: chanPubLoaded, - }, c.api.GetCmix(), c.api.GetRng()) - if err != nil { - return nil, errors.WithMessage(err, "Failed to create broadcast channel client") - } - - return &Channel{ch: ch}, nil -} - -// Listen registers a BroadcastListener for a given method. This allows users to -// handle incoming broadcast messages. -// -// Parameters: -// - l - BroadcastListener object -// - method - int corresponding to broadcast.Method constant, 0 for symmetric -// or 1 for asymmetric -func (c *Channel) Listen(l BroadcastListener, method int) error { - broadcastMethod := broadcast.Method(method) - listen := func(payload []byte, - receptionID receptionID.EphemeralIdentity, round rounds.Round) { - l.Callback(json.Marshal(&BroadcastMessage{ - BroadcastReport: BroadcastReport{ - RoundsList: makeRoundsList(round.ID), - RoundURL: getRoundURL(round.ID), - EphID: receptionID.EphId, - }, - Payload: payload, - })) - } - return c.ch.RegisterListener(listen, broadcastMethod) -} - -// Broadcast sends a given payload over the broadcast channel using symmetric -// broadcast. -// -// Returns: -// - []byte - the JSON marshalled bytes of the BroadcastReport object, which -// can be passed into Cmix.WaitForRoundResult to see if the broadcast -// succeeded. -func (c *Channel) Broadcast(payload []byte) ([]byte, error) { - rid, eid, err := c.ch.Broadcast(payload, cmix.GetDefaultCMIXParams()) - if err != nil { - return nil, err - } - return json.Marshal(BroadcastReport{ - RoundURL: getRoundURL(rid.ID), - RoundsList: makeRoundsList(rid.ID), - EphID: eid, - }) -} - -// BroadcastAsymmetric sends a given payload over the broadcast channel using -// asymmetric broadcast. This mode of encryption requires a private key. -// -// Returns: -// - []byte - the JSON marshalled bytes of the BroadcastReport object, which -// can be passed into WaitForRoundResult to see if the broadcast succeeded. -func (c *Channel) BroadcastAsymmetric(payload, pk []byte) ([]byte, error) { - pkLoaded, err := rsa.LoadPrivateKeyFromPem(pk) - if err != nil { - return nil, err - } - rid, eid, err := c.ch.BroadcastAsymmetric(pkLoaded, payload, cmix.GetDefaultCMIXParams()) - if err != nil { - return nil, err - } - return json.Marshal(BroadcastReport{ - RoundsList: makeRoundsList(rid.ID), - RoundURL: getRoundURL(rid.ID), - EphID: eid, - }) -} - -// MaxPayloadSize returns the maximum possible payload size which can be -// broadcast. -func (c *Channel) MaxPayloadSize() int { - return c.ch.MaxPayloadSize() -} - -// MaxAsymmetricPayloadSize returns the maximum possible payload size which can -// be broadcast. -func (c *Channel) MaxAsymmetricPayloadSize() int { - return c.ch.MaxAsymmetricPayloadSize() -} - -// Get returns the result of calling json.Marshal on a ChannelDef based on the -// underlying crypto broadcast.Channel. -func (c *Channel) Get() ([]byte, error) { - def := c.ch.Get() - return json.Marshal(&ChannelDef{ - Name: def.Name, - Description: def.Description, - Salt: def.Salt, - PubKey: rsa.CreatePublicKeyPem(def.RsaPubKey), - }) -} - -// Stop stops the channel from listening for more messages. -func (c *Channel) Stop() { - c.ch.Stop() -} diff --git a/bindings/broadcast_test.go b/bindings/broadcast_test.go deleted file mode 100644 index bb7d93d52431b545d536b53742f49ee75ba786f4..0000000000000000000000000000000000000000 --- a/bindings/broadcast_test.go +++ /dev/null @@ -1,75 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2022 xx foundation // -// // -// Use of this source code is governed by a license that can be found in the // -// LICENSE file. // -//////////////////////////////////////////////////////////////////////////////// - -package bindings - -import ( - "encoding/json" - "gitlab.com/elixxir/crypto/cmix" - "gitlab.com/xx_network/crypto/csprng" - "gitlab.com/xx_network/crypto/signature/rsa" - "gitlab.com/xx_network/primitives/id" - "gitlab.com/xx_network/primitives/id/ephemeral" - "testing" - "time" -) - -func TestChannelDef_JSON(t *testing.T) { - rng := csprng.NewSystemRNG() - rng.SetSeed([]byte("rng")) - pk, _ := rsa.GenerateKey(rng, 256) - cd := ChannelDef{ - Name: "My broadcast channel", - Description: "A broadcast channel for me to test things", - Salt: cmix.NewSalt(rng, 16), - PubKey: rsa.CreatePublicKeyPem(pk.GetPublic()), - } - - cdJson, err := json.Marshal(cd) - if err != nil { - t.Errorf("Failed to marshal channel def: %+v", err) - } - t.Log(string(cdJson)) -} - -func TestBroadcastMessage_JSON(t *testing.T) { - uid := id.NewIdFromString("zezima", id.User, t) - eid, _, _, err := ephemeral.GetId(uid, 16, time.Now().UnixNano()) - if err != nil { - t.Errorf("Failed to form ephemeral ID: %+v", err) - } - bm := BroadcastMessage{ - BroadcastReport: BroadcastReport{ - RoundsList: makeRoundsList(42), - EphID: eid, - }, - Payload: []byte("Hello, broadcast friends!"), - } - bmJson, err := json.Marshal(bm) - if err != nil { - t.Errorf("Failed to marshal broadcast message: %+v", err) - } - t.Log(string(bmJson)) -} - -func TestBroadcastReport_JSON(t *testing.T) { - uid := id.NewIdFromString("zezima", id.User, t) - eid, _, _, err := ephemeral.GetId(uid, 16, time.Now().UnixNano()) - if err != nil { - t.Errorf("Failed to form ephemeral ID: %+v", err) - } - br := BroadcastReport{ - RoundsList: makeRoundsList(42), - EphID: eid, - } - - brJson, err := json.Marshal(br) - if err != nil { - t.Errorf("Failed to marshal broadcast report: %+v", err) - } - t.Log(string(brJson)) -} diff --git a/bindings/channels.go b/bindings/channels.go index 22241047505d684478e27ea02aad4e0a195b39d9..ab47f58ab97d2122afb7b00690fa7b2c6ff9f15f 100644 --- a/bindings/channels.go +++ b/bindings/channels.go @@ -15,7 +15,7 @@ import ( "gitlab.com/elixxir/client/xxdk" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" cryptoChannel "gitlab.com/elixxir/crypto/channel" - "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/elixxir/crypto/rsa" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" "sync" @@ -134,117 +134,161 @@ func NewChannelsManager(e2eID, udID int) (*ChannelsManager, error) { return channelManagerTrackerSingleton.make(m), nil } -// JoinChannel joins the given channel. It will fail if the channel has already -// been joined. -// +// NewChannelsManagerGoEventModel constructs a ChannelsManager. This is not +// compatible with GoMobile Bindings because it receives the go event model // Parameters: -// - channelJson - A JSON encoded [ChannelDef]. -func (cm *ChannelsManager) JoinChannel(channelJson []byte) error { - // Unmarshal channel definition - def := ChannelDef{} - err := json.Unmarshal(channelJson, &def) +// - e2eID - The tracked e2e object ID. This can be retrieved using +// [E2e.GetID]. +// - udID - The tracked UD object ID. This can be retrieved using +// [UserDiscovery.GetID]. +func NewChannelsManagerGoEventModel(e2eID, udID int, + goEvent channels.EventModel) (*ChannelsManager, error) { + // Get user from singleton + user, err := e2eTrackerSingleton.get(e2eID) if err != nil { - return err + return nil, err } - // Construct ID using the embedded cryptographic information - channelId, err := cryptoBroadcast.NewChannelID(def.Name, def.Description, - def.Salt, def.PubKey) + udMan, err := udTrackerSingleton.get(udID) if err != nil { - return err + return nil, err } - // Construct public key into object - rsaPubKey, err := rsa.LoadPublicKeyFromPem(def.PubKey) + nameService, err := udMan.api.StartChannelNameService() if err != nil { - return err + return nil, err } - // Construct cryptographic channel object - channel := &cryptoBroadcast.Channel{ - ReceptionID: channelId, - Name: def.Name, - Description: def.Description, - Salt: def.Salt, - RsaPubKey: rsaPubKey, - } + // Construct new channels manager + m := channels.NewManager(user.api.GetStorage().GetKV(), user.api.GetCmix(), + user.api.GetRng(), nameService, goEvent) - // Join the channel using the API - return cm.api.JoinChannel(channel) + // Add channel to singleton and return + return channelManagerTrackerSingleton.make(m), nil } -// GetChannels returns the IDs of all channels that have been joined. -// -// Returns: -// - []byte - A JSON marshalled list of IDs. -// -// JSON Example: -// { -// U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID", -// "15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAgD" -// } -func (cm *ChannelsManager) GetChannels() ([]byte, error) { - channelIds := cm.api.GetChannels() - return json.Marshal(channelIds) +type ChannelGeneration struct { + Channel string + PrivateKey string } -// GetChannelId returns the ID of the channel given the channel's cryptographic -// information. +// GenerateChannel is used to create a channel. This makes a new channel +// of which your are the admin. It is only for making new channels, not +// joining existing ones. +// it returns a prettyPrint of the channel and the private key +// The name cannot be longer that ____ characters +// the description cannot be longer than ___ and can only use ______ characters // // Parameters: -// - channelJson - A JSON encoded [ChannelDef]. This may be retrieved from -// [Channel.Get], for example. -// +// - cmixID - The tracked cmix object ID. This can be retrieved using +// [Cmix.GetID]. +// - name - the name of the new channel. The name cannot be longer than ____ +// characters and must contain only _____ characters. It cannot be changed +// once a channel is created. +// - description - The description of a channel. The description cannot be +// longer than ____ characters and must contain only _____ characters. It +// cannot be changed once a channel is created. // Returns: -// - []byte - A JSON encoded channel ID ([id.ID]). -// -// JSON Example: -// "dGVzdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD" -func (cm *ChannelsManager) GetChannelId(channelJson []byte) ([]byte, error) { - def := ChannelDef{} - err := json.Unmarshal(channelJson, &def) +// - []byte - ChannelGeneration describes a generated channel. it contains both +// the public channel info and the private key for the channel in PEM format +// fixme: document json +func GenerateChannel(cmixID int, name, description string) ([]byte, error) { + // Get cmix from singleton so its rng can be used + cmix, err := cmixTrackerSingleton.get(cmixID) if err != nil { return nil, err } - channelId, err := cryptoBroadcast.NewChannelID(def.Name, def.Description, - def.Salt, def.PubKey) + stream := cmix.api.GetRng().GetStream() + defer stream.Close() + c, pk, err := cryptoBroadcast.NewChannel(name, description, cmix.api.GetCmix().GetMaxMessageLength(), stream) if err != nil { return nil, err } - return json.Marshal(channelId) + gen := ChannelGeneration{ + Channel: c.PrettyPrint(), + PrivateKey: string(pk.MarshalPem()), + } + + return json.Marshal(&gen) +} + +type ChannelInfo struct { + Name string + Description string + ChannelID string } -// GetChannel returns the underlying cryptographic structure for a given -// channel. +// GetChannelInfo returns the info about a channel from its public description // // Parameters: -// - marshalledChanId - A JSON marshalled channel ID ([id.ID]). This may be -// retrieved using ChannelsManager.GetChannelId. -// +// - prettyPrint - The pretty print of the channel. Of the format: +// "<XXChannel-v1:Test Channel,description:This is a test channel,secrets:pn +// 0kIs6P1pHvAe7u8kUyf33GYVKmkoCX9LhCtvKJZQI=,3A5eB5pzSHyxN09w1kOVrTIEr5Uy +// Bbzmmd9Ga5Dx0XA=,0,0,/zChIlLr2p3Vsm2X4+3TiFapoapaTi8EJIisJSqwfGc=>" // Returns: -// - []byte - A JSON marshalled ChannelDef. -func (cm *ChannelsManager) GetChannel(marshalledChanId []byte) ([]byte, error) { - // Unmarshal ID - chanId, err := id.Unmarshal(marshalledChanId) +// - []byte - ChannelInfo describes all relevant channel info. +// fixme: document json +func GetChannelInfo(prettyPrint string) ([]byte, error) { + _, bytes, err := getChannelInfo(prettyPrint) + return bytes, err +} + +func getChannelInfo(prettyPrint string) (*cryptoBroadcast.Channel, []byte, error) { + c, err := cryptoBroadcast.NewChannelFromPrettyPrint(prettyPrint) if err != nil { - return nil, err + return nil, nil, err + } + ci := &ChannelInfo{ + Name: c.Name, + Description: c.Description, + ChannelID: c.ReceptionID.String(), + } + bytes, err := json.Marshal(ci) + if err != nil { + return nil, nil, err } + return c, bytes, nil +} - // Retrieve channel from manager - def, err := cm.api.GetChannel(chanId) +// JoinChannel joins the given channel. It will fail if the channel has already +// been joined. +// +// Parameters: +// - channelPretty - A portable channel string. Should be received from +// another user or generated via GenerateChannel(). +// "<XXChannel-v1:Test Channel,description:This is a test channel,secrets:pn +// 0kIs6P1pHvAe7u8kUyf33GYVKmkoCX9LhCtvKJZQI=,3A5eB5pzSHyxN09w1kOVrTIEr5Uy +// Bbzmmd9Ga5Dx0XA=,0,0,/zChIlLr2p3Vsm2X4+3TiFapoapaTi8EJIisJSqwfGc=>" +// Returns: +// - []byte - ChannelInfo describes all relevant channel info. +// fixme: document json +func (cm *ChannelsManager) JoinChannel(channelPretty string) ([]byte, error) { + c, info, err := getChannelInfo(channelPretty) if err != nil { return nil, err } - // Marshal channel - return json.Marshal(&ChannelDef{ - Name: def.Name, - Description: def.Description, - Salt: def.Salt, - PubKey: rsa.CreatePublicKeyPem(def.RsaPubKey), - }) + // Join the channel using the API + err = cm.api.JoinChannel(c) + + return info, err +} + +// GetChannels returns the IDs of all channels that have been joined. +// +// Returns: +// - []byte - A JSON marshalled list of IDs. +// +// JSON Example: +// { +// U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID", +// "15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAgD" +// } +func (cm *ChannelsManager) GetChannels() ([]byte, error) { + channelIds := cm.api.GetChannels() + return json.Marshal(channelIds) } // LeaveChannel leaves the given channel. It will return an error if the @@ -381,7 +425,7 @@ func (cm *ChannelsManager) SendAdminGeneric(adminPrivateKey, cmixParamsJSON []byte) ([]byte, error) { // Load private key from file - rsaPrivKey, err := rsa.LoadPrivateKeyFromPem(adminPrivateKey) + rsaPrivKey, err := rsa.GetScheme().UnmarshalPrivateKeyPEM(adminPrivateKey) if err != nil { return nil, err } diff --git a/broadcast/client.go b/broadcast/client.go index 05926f523cf0ea5b03c447040fd5808a11ad063a..63d2c03ce4e5354fdca08b60b0c539849573e156 100644 --- a/broadcast/client.go +++ b/broadcast/client.go @@ -14,7 +14,6 @@ import ( "gitlab.com/elixxir/client/cmix/message" crypto "gitlab.com/elixxir/crypto/broadcast" "gitlab.com/elixxir/crypto/fastRNG" - "gitlab.com/xx_network/crypto/signature/rsa" ) // broadcastClient implements the Channel interface for sending/receiving asymmetric or symmetric broadcast messages @@ -34,7 +33,7 @@ func NewBroadcastChannel(channel *crypto.Channel, net Client, rng *fastRNG.Strea rng: rng, } - if !bc.verifyID() { + if !channel.Verify() { return nil, errors.New("Failed ID verification for broadcast channel") } @@ -53,8 +52,8 @@ func (bc *broadcastClient) RegisterListener(listenerCb ListenerFunc, method Meth switch method { case Symmetric: tag = symmetricBroadcastServiceTag - case Asymmetric: - tag = asymmetricBroadcastServiceTag + case RSAToPublic: + tag = asymmetricRSAToPublicBroadcastServiceTag default: return errors.Errorf("Cannot register listener for broadcast method %s", method) } @@ -89,26 +88,22 @@ func (bc *broadcastClient) Get() *crypto.Channel { return bc.channel } -// verifyID generates a symmetric ID based on the info in the channel and -// compares it to the one passed in. -func (bc *broadcastClient) verifyID() bool { - gen, err := crypto.NewChannelID(bc.channel.Name, bc.channel.Description, - bc.channel.Salt, rsa.CreatePublicKeyPem(bc.channel.RsaPubKey)) - if err != nil { - jww.FATAL.Panicf("[verifyID] Failed to generate verified channel ID") - return false - } - return bc.channel.ReceptionID.Cmp(gen) -} - +// MaxPayloadSize returns the maximum payload size for a symmetric broadcast func (bc *broadcastClient) MaxPayloadSize() int { return bc.maxSymmetricPayload() } -func (bc *broadcastClient) MaxAsymmetricPayloadSize() int { - return bc.maxAsymmetricPayloadSizeRaw() - internalPayloadSizeLength +func (bc *broadcastClient) maxSymmetricPayload() int { + return bc.channel.GetMaxSymmetricPayloadSize(bc.net.GetMaxMessageLength()) +} + +// MaxRSAToPublicPayloadSize return the maximum payload size for an RSAToPublic +// Asymmetric payload +func (bc *broadcastClient) MaxRSAToPublicPayloadSize() int { + return bc.maxRSAToPublicPayloadSizeRaw() - internalPayloadSizeLength } -func (bc *broadcastClient) maxAsymmetricPayloadSizeRaw() int { - return bc.channel.MaxAsymmetricPayloadSize() +func (bc *broadcastClient) maxRSAToPublicPayloadSizeRaw() int { + size, _, _ := bc.channel.GetRSAToPublicMessageLength() + return size } diff --git a/broadcast/interface.go b/broadcast/interface.go index 68d8eba25a02cb00e0557537317ad3ea2457a721..034550f0ba8def0de3639c13f9060a18baed17da 100644 --- a/broadcast/interface.go +++ b/broadcast/interface.go @@ -13,7 +13,7 @@ import ( "gitlab.com/elixxir/client/cmix/message" "gitlab.com/elixxir/client/cmix/rounds" crypto "gitlab.com/elixxir/crypto/broadcast" - "gitlab.com/xx_network/crypto/multicastRSA" + "gitlab.com/elixxir/crypto/rsa" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" "time" @@ -29,38 +29,38 @@ type Channel interface { // MaxPayloadSize returns the maximum size for a symmetric broadcast payload MaxPayloadSize() int - // MaxAsymmetricPayloadSize returns the maximum size for an asymmetric + // MaxRSAToPublicPayloadSize returns the maximum size for an asymmetric // broadcast payload - MaxAsymmetricPayloadSize() int + MaxRSAToPublicPayloadSize() int // Get returns the underlying crypto.Channel Get() *crypto.Channel // Broadcast broadcasts the payload to the channel. The payload size must be - // equal to MaxPayloadSize. + // equal to MaxPayloadSize or smaller. Broadcast(payload []byte, cMixParams cmix.CMIXParams) ( rounds.Round, ephemeral.Id, error) // BroadcastWithAssembler broadcasts a payload over a symmetric channel. // With a payload assembled after the round is selected, allowing the round // info to be included in the payload. Network must be healthy to send. - // Requires a payload of size bc.MaxSymmetricPayloadSize() + // Requires a payload of size bc.MaxSymmetricPayloadSize() or smaller BroadcastWithAssembler(assembler Assembler, cMixParams cmix.CMIXParams) ( rounds.Round, ephemeral.Id, error) - // BroadcastAsymmetric broadcasts the payload to the channel. Requires a - // healthy network state to send. Payload length must be equal to - // bc.MaxAsymmetricPayloadSize and the channel PrivateKey must be passed in - BroadcastAsymmetric(pk multicastRSA.PrivateKey, payload []byte, + // BroadcastRSAtoPublic broadcasts the payload to the channel. Requires a + // healthy network state to send Payload length less than or equal to + // bc.MaxRSAToPublicPayloadSize, and the channel PrivateKey must be passed in + BroadcastRSAtoPublic(pk rsa.PrivateKey, payload []byte, cMixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) - // BroadcastAsymmetricWithAssembler broadcasts the payload to the channel. - // Requires a healthy network state to send. Payload length must be equal to - // bc.MaxAsymmetricPayloadSize and the channel PrivateKey must be passed in. - // The assembler will run once a round is selected and will receive the - // round ID - BroadcastAsymmetricWithAssembler( - pk multicastRSA.PrivateKey, assembler Assembler, + // BroadcastRSAToPublicWithAssembler broadcasts the payload to the channel with + // a function which builds the payload based upon the ID of the selected round. + // Requires a healthy network state to send Payload must be shorter or equal in + // length to bc.MaxRSAToPublicPayloadSize when returned, and the channel + // PrivateKey must be passed in + BroadcastRSAToPublicWithAssembler( + pk rsa.PrivateKey, assembler Assembler, cMixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) // RegisterListener registers a listener for broadcast messages @@ -77,7 +77,6 @@ type Assembler func(rid id.Round) (payload []byte, err error) // Client contains the methods from cmix.Client that are required by // symmetricClient. type Client interface { - GetMaxMessageLength() int SendWithAssembler(recipient *id.ID, assembler cmix.MessageAssembler, cmixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) IsHealthy() bool @@ -86,4 +85,5 @@ type Client interface { response message.Processor) DeleteClientService(clientID *id.ID) RemoveIdentity(id *id.ID) + GetMaxMessageLength() int } diff --git a/broadcast/method.go b/broadcast/method.go index 8e93ea57dba204b2f616071e54d7317bcec96624..c154fc027b81a55f600c5f54fa3847aa7616ea89 100644 --- a/broadcast/method.go +++ b/broadcast/method.go @@ -12,15 +12,18 @@ type Method uint8 const ( Symmetric Method = iota - Asymmetric + RSAToPublic + RSAToPrivate ) func (m Method) String() string { switch m { case Symmetric: return "Symmetric" - case Asymmetric: - return "Asymmetric" + case RSAToPublic: + return "RSAToPublic" + case RSAToPrivate: + return "RSAToPrivate" default: return "Unknown" } diff --git a/broadcast/processor.go b/broadcast/processor.go index 04b00ba35b2ba84a4a691f77970f74cacb07e50e..8ee1f85d07ad093337711ef15e7f6e3ced3dd1f8 100644 --- a/broadcast/processor.go +++ b/broadcast/processor.go @@ -35,10 +35,8 @@ func (p *processor) Process(msg format.Message, var payload []byte var err error switch p.method { - case Asymmetric: - encPartSize := p.c.RsaPubKey.Size() // Size returned by multicast RSA encryption - encodedMessage := msg.GetContents()[:encPartSize] // Only one message is encoded, rest of it is random data - decodedMessage, decryptErr := p.c.DecryptAsymmetric(encodedMessage) + case RSAToPublic: + decodedMessage, decryptErr := p.c.DecryptRSAToPublic(msg.GetContents(), msg.GetMac(), msg.GetKeyFP()) if decryptErr != nil { jww.ERROR.Printf(errDecrypt, p.c.ReceptionID, p.c.Name, decryptErr) return diff --git a/broadcast/processor_test.go b/broadcast/processor_test.go index ae0df4b4e4cdcec92a9fea7d2bf607c5616ef038..b758c20dbfa8756a31cc554671ab884d6b312a56 100644 --- a/broadcast/processor_test.go +++ b/broadcast/processor_test.go @@ -7,20 +7,7 @@ package broadcast -import ( - "bytes" - "gitlab.com/elixxir/client/cmix/identity/receptionID" - "gitlab.com/elixxir/client/cmix/rounds" - crypto "gitlab.com/elixxir/crypto/broadcast" - "gitlab.com/elixxir/crypto/cmix" - "gitlab.com/elixxir/primitives/format" - "gitlab.com/xx_network/crypto/csprng" - "gitlab.com/xx_network/crypto/signature/rsa" - "gitlab.com/xx_network/primitives/id" - "testing" - "time" -) - +/* // Tests that process.Process properly decrypts the payload and passes it to the // callback. func Test_processor_Process(t *testing.T) { @@ -67,4 +54,4 @@ func Test_processor_Process(t *testing.T) { case <-time.After(15 * time.Millisecond): t.Error("Timed out waiting for listener channel to be called.") } -} +}*/ diff --git a/broadcast/asymmetric.go b/broadcast/rsaToPublic.go similarity index 70% rename from broadcast/asymmetric.go rename to broadcast/rsaToPublic.go index 4a07061f0bccb20a299f15aa74087b7396d01d58..0d1483b16437854f99fa4a31e5cd7c5050705f8e 100644 --- a/broadcast/asymmetric.go +++ b/broadcast/rsaToPublic.go @@ -13,38 +13,38 @@ import ( "gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix/message" "gitlab.com/elixxir/client/cmix/rounds" + "gitlab.com/elixxir/crypto/rsa" "gitlab.com/elixxir/primitives/format" - "gitlab.com/xx_network/crypto/multicastRSA" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" ) const ( - asymmetricBroadcastServiceTag = "AsymmBcast" - asymmCMixSendTag = "AsymmetricBroadcast" - internalPayloadSizeLength = 2 + asymmetricRSAToPublicBroadcastServiceTag = "AsymmToPublicBcast" + asymmCMixSendTag = "AsymmetricBroadcast" + internalPayloadSizeLength = 2 ) -// BroadcastAsymmetric broadcasts the payload to the channel. Requires a -// healthy network state to send Payload length must be equal to -// bc.MaxAsymmetricPayloadSize, and the channel PrivateKey must be passed in -func (bc *broadcastClient) BroadcastAsymmetric(pk multicastRSA.PrivateKey, +// BroadcastRSAtoPublic broadcasts the payload to the channel. Requires a +// healthy network state to send Payload length less than or equal to +// bc.MaxRSAToPublicPayloadSize, and the channel PrivateKey must be passed in +func (bc *broadcastClient) BroadcastRSAtoPublic(pk rsa.PrivateKey, payload []byte, cMixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) { // Confirm network health assemble := func(rid id.Round) ([]byte, error) { return payload, nil } - return bc.BroadcastAsymmetricWithAssembler(pk, assemble, cMixParams) + return bc.BroadcastRSAToPublicWithAssembler(pk, assemble, cMixParams) } -// BroadcastAsymmetricWithAssembler broadcasts the payload to the channel with +// BroadcastRSAToPublicWithAssembler broadcasts the payload to the channel with // a function which builds the payload based upon the ID of the selected round. -// Requires a healthy network state to send Payload must be equal to -// bc.MaxAsymmetricPayloadSize when returned, and the channel PrivateKey -// must be passed in -func (bc *broadcastClient) BroadcastAsymmetricWithAssembler( - pk multicastRSA.PrivateKey, assembler Assembler, +// Requires a healthy network state to send Payload must be shorter or equal in +// length to bc.MaxRSAToPublicPayloadSize when returned, and the channel +// PrivateKey must be passed in +func (bc *broadcastClient) BroadcastRSAToPublicWithAssembler( + pk rsa.PrivateKey, assembler Assembler, cMixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) { // Confirm network health if !bc.net.IsHealthy() { @@ -59,21 +59,22 @@ func (bc *broadcastClient) BroadcastAsymmetricWithAssembler( nil, err } // Check payload size - if len(payload) > bc.MaxAsymmetricPayloadSize() { + if len(payload) > bc.MaxRSAToPublicPayloadSize() { return format.Fingerprint{}, message.Service{}, nil, nil, errors.Errorf(errPayloadSize, len(payload), - bc.MaxAsymmetricPayloadSize()) + bc.MaxRSAToPublicPayloadSize()) } payloadLength := uint16(len(payload)) - finalPayload := make([]byte, bc.maxAsymmetricPayloadSizeRaw()) + finalPayload := make([]byte, bc.maxRSAToPublicPayloadSizeRaw()) binary.BigEndian.PutUint16(finalPayload[:internalPayloadSizeLength], payloadLength) copy(finalPayload[internalPayloadSizeLength:], payload) // Encrypt payload encryptedPayload, mac, fp, err = - bc.channel.EncryptAsymmetric(finalPayload, pk, bc.rng.GetStream()) + bc.channel.EncryptRSAToPublic(finalPayload, pk, bc.net.GetMaxMessageLength(), + bc.rng.GetStream()) if err != nil { return format.Fingerprint{}, message.Service{}, nil, nil, errors.WithMessage(err, "Failed to encrypt "+ @@ -85,7 +86,7 @@ func (bc *broadcastClient) BroadcastAsymmetricWithAssembler( // this channel service = message.Service{ Identifier: bc.channel.ReceptionID.Bytes(), - Tag: asymmetricBroadcastServiceTag, + Tag: asymmetricRSAToPublicBroadcastServiceTag, } if cMixParams.DebugTag == cmix.DefaultDebugTag { diff --git a/broadcast/asymmetric_test.go b/broadcast/rsaToPublic_test.go similarity index 78% rename from broadcast/asymmetric_test.go rename to broadcast/rsaToPublic_test.go index ca5c213b69a221b9c8d846a119d042ad808cd8cd..159f9d1016ead09866c8db1bd3f15faedfc94404 100644 --- a/broadcast/asymmetric_test.go +++ b/broadcast/rsaToPublic_test.go @@ -16,14 +16,12 @@ import ( "time" "gitlab.com/xx_network/crypto/csprng" - "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/message" "gitlab.com/elixxir/client/cmix/rounds" crypto "gitlab.com/elixxir/crypto/broadcast" - cMixCrypto "gitlab.com/elixxir/crypto/cmix" "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/primitives/format" ) @@ -56,40 +54,27 @@ func (p *mockProcessor) String() string { return "hello" } func Test_asymmetricClient_Smoke(t *testing.T) { cMixHandler := newMockCmixHandler() rngGen := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG) - pk, err := rsa.GenerateKey(rngGen.GetStream(), 4096) - if err != nil { - t.Fatalf("Failed to generate priv key: %+v", err) - } cName := "MyChannel" cDesc := "This is my channel about stuff." - cSalt := cMixCrypto.NewSalt(csprng.NewSystemRNG(), 32) - cPubKey := pk.GetPublic() - cid, err := crypto.NewChannelID( - cName, cDesc, cSalt, rsa.CreatePublicKeyPem(cPubKey)) - if err != nil { - t.Errorf("Failed to create channel ID: %+v", err) - } - channel := &crypto.Channel{ - ReceptionID: cid, - Name: cName, - Description: cDesc, - Salt: cSalt, - RsaPubKey: cPubKey, - } + packetPayloadLength := newMockCmix(cMixHandler).GetMaxMessageLength() + + channel, pk, _ := crypto.NewChannel( + cName, cDesc, packetPayloadLength, rngGen.GetStream()) + cid := channel.ReceptionID - // must mutate cMixHandler such that it's processorMap contains a + // Must mutate cMixHandler such that it's processorMap contains a // message.Processor - processor := newMockProcessor() + mockProc := newMockProcessor() cMixHandler.processorMap[*cid] = make(map[string][]message.Processor) - cMixHandler.processorMap[*cid]["AsymmBcast"] = []message.Processor{processor} + cMixHandler.processorMap[*cid]["AsymmBcast"] = []message.Processor{mockProc} const n = 1 cbChans := make([]chan []byte, n) clients := make([]Channel, n) for i := range clients { cbChan := make(chan []byte, 10) - cb := func(payload []byte, _ receptionID.EphemeralIdentity, - _ rounds.Round) { + cb := func( + payload []byte, _ receptionID.EphemeralIdentity, _ rounds.Round) { cbChan <- payload } @@ -98,7 +83,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) { t.Errorf("Failed to create broadcast channel: %+v", err) } - err = s.RegisterListener(cb, Asymmetric) + err = s.RegisterListener(cb, RSAToPublic) if err != nil { t.Errorf("Failed to register listener: %+v", err) } @@ -106,7 +91,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) { cbChans[i] = cbChan clients[i] = s - // Test that Get returns the expected channel + // Test that Channel.Get returns the expected channel if !reflect.DeepEqual(s.Get(), channel) { t.Errorf("Cmix %d returned wrong channel."+ "\nexpected: %+v\nreceived: %+v", i, channel, s.Get()) @@ -115,7 +100,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) { // Send broadcast from each client for i := range clients { - payload := make([]byte, clients[i].MaxAsymmetricPayloadSize()) + payload := make([]byte, clients[i].MaxRSAToPublicPayloadSize()) copy(payload, fmt.Sprintf("Hello from client %d of %d.", i, len(clients))) @@ -140,7 +125,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) { } // Broadcast payload - _, _, err = clients[i].BroadcastAsymmetric( + _, _, err := clients[i].BroadcastRSAtoPublic( pk, payload, cmix.GetDefaultCMIXParams()) if err != nil { t.Errorf("Cmix %d failed to send broadcast: %+v", i, err) @@ -155,7 +140,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) { clients[i].Stop() } - payload := make([]byte, clients[0].MaxAsymmetricPayloadSize()) + payload := make([]byte, clients[0].MaxRSAToPublicPayloadSize()) copy(payload, "This message should not get through.") // Start waiting on channels and error if anything is received @@ -173,7 +158,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) { } // Broadcast payload - _, _, err = clients[0].BroadcastAsymmetric(pk, payload, cmix.GetDefaultCMIXParams()) + _, _, err := clients[0].BroadcastRSAtoPublic(pk, payload, cmix.GetDefaultCMIXParams()) if err != nil { t.Errorf("Cmix 0 failed to send broadcast: %+v", err) } diff --git a/broadcast/sizedBroadcast.go b/broadcast/sizedBroadcast.go deleted file mode 100644 index c91230fa8369af630c5538775acce785bb08062e..0000000000000000000000000000000000000000 --- a/broadcast/sizedBroadcast.go +++ /dev/null @@ -1,93 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2022 xx foundation // -// // -// Use of this source code is governed by a license that can be found in the // -// LICENSE file. // -//////////////////////////////////////////////////////////////////////////////// - -package broadcast - -import ( - "encoding/binary" - "github.com/pkg/errors" -) - -// Message field sizes. -const ( - sizeSize = 2 - sizedBroadcastMinSize = sizeSize -) - -// Error messages. -const ( - // NewSizedBroadcast - errNewSizedBroadcastMaxSize = "size of payload and its size %d too large to fit in max payload size %d" - - // DecodeSizedBroadcast - errDecodeSizedBroadcastDataLen = "size of data %d must be greater than %d" - errDecodeSizedBroadcastSize = "stated payload size %d larger than provided data %d" -) - -/* -+---------------------------+ -| cMix Message Contents | -+---------+-----------------+ -| Size | Payload | -| 2 bytes | remaining space | -+---------+-----------------+ -*/ - -// NewSizedBroadcast creates a new broadcast payload of size maxPayloadSize that -// contains the given payload so that it fits completely inside a broadcasted -// cMix message payload. The length of the payload is stored internally and used -// to strip extraneous padding when decoding the payload. -// The maxPayloadSize is the maximum size of the resulting payload. Returns an -// error when the provided payload cannot fit in the max payload size. -func NewSizedBroadcast(maxPayloadSize int, payload []byte) ([]byte, error) { - if len(payload)+sizedBroadcastMinSize > maxPayloadSize { - return nil, errors.Errorf(errNewSizedBroadcastMaxSize, - len(payload)+sizedBroadcastMinSize, maxPayloadSize) - } - - b := make([]byte, sizeSize) - binary.LittleEndian.PutUint16(b, uint16(len(payload))) - - sizedPayload := make([]byte, maxPayloadSize) - copy(sizedPayload, append(b, payload...)) - - return sizedPayload, nil -} - -// DecodeSizedBroadcast decodes the data into its original payload stripping off -// extraneous padding. -func DecodeSizedBroadcast(data []byte) ([]byte, error) { - if len(data) < sizedBroadcastMinSize { - return nil, errors.Errorf( - errDecodeSizedBroadcastDataLen, len(data), sizedBroadcastMinSize) - } - - size := GetSizedBroadcastSize(data) - if int(size) > len(data[sizeSize:]) { - return nil, errors.Errorf( - errDecodeSizedBroadcastSize, size, len(data[sizeSize:])) - } - - return data[sizeSize : size+sizeSize], nil -} - -// GetSizedBroadcastSize returns the size of the sized broadcast, used for -// testing -func GetSizedBroadcastSize(data []byte) uint16 { - if len(data) < sizeSize { - return 0 - } - - return binary.LittleEndian.Uint16(data[:sizeSize]) -} - -// MaxSizedBroadcastPayloadSize returns the maximum size of a payload that can -// fit in a sized broadcast message for the given maximum cMix message payload -// size. -func MaxSizedBroadcastPayloadSize(maxPayloadSize int) int { - return maxPayloadSize - sizedBroadcastMinSize -} diff --git a/broadcast/sizedBroadcast_test.go b/broadcast/sizedBroadcast_test.go deleted file mode 100644 index d81b439c097574e0c58d35525da79d14a1334471..0000000000000000000000000000000000000000 --- a/broadcast/sizedBroadcast_test.go +++ /dev/null @@ -1,115 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2022 xx foundation // -// // -// Use of this source code is governed by a license that can be found in the // -// LICENSE file. // -//////////////////////////////////////////////////////////////////////////////// - -package broadcast - -import ( - "bytes" - "fmt" - "testing" -) - -// Tests that a payload smaller than the max payload size encoded via -// NewSizedBroadcast and decoded via DecodeSizedBroadcast matches the original. -func TestNewSizedBroadcast_DecodeSizedBroadcast_SmallPayload(t *testing.T) { - const maxPayloadSize = 512 - payload := []byte("This is my payload message.") - - data, err := NewSizedBroadcast(maxPayloadSize, payload) - if err != nil { - t.Errorf("NewSizedBroadcast returned an error: %+v", err) - } - - decodedPayload, err := DecodeSizedBroadcast(data) - if err != nil { - t.Errorf("DecodeSizedBroadcast returned an error: %+v", err) - } - - if !bytes.Equal(payload, decodedPayload) { - t.Errorf("Decoded payload does not match original."+ - "\nexpected: %q\nreceived: %q", payload, decodedPayload) - } -} - -// Tests that a payload the same size as the max payload size encoded via -// NewSizedBroadcast and decoded via DecodeSizedBroadcast matches the original. -func TestNewSizedBroadcast_DecodeSizedBroadcast_FullSizesPayload(t *testing.T) { - payload := []byte("This is my payload message.") - maxPayloadSize := len(payload) + sizeSize - - data, err := NewSizedBroadcast(maxPayloadSize, payload) - if err != nil { - t.Errorf("NewSizedBroadcast returned an error: %+v", err) - } - - decodedPayload, err := DecodeSizedBroadcast(data) - if err != nil { - t.Errorf("DecodeSizedBroadcast returned an error: %+v", err) - } - - if !bytes.Equal(payload, decodedPayload) { - t.Errorf("Decoded payload does not match original."+ - "\nexpected: %q\nreceived: %q", payload, decodedPayload) - } -} - -// Error path: tests that NewSizedBroadcast returns an error when the payload is -// larger than the max payload size. -func TestNewSizedBroadcast_MaxPayloadSizeError(t *testing.T) { - payload := []byte("This is my payload message.") - maxPayloadSize := len(payload) - expectedErr := fmt.Sprintf(errNewSizedBroadcastMaxSize, - len(payload)+sizedBroadcastMinSize, maxPayloadSize) - - _, err := NewSizedBroadcast(maxPayloadSize, payload) - if err == nil || err.Error() != expectedErr { - t.Errorf("NewSizedBroadcast did not return the expected error when "+ - "the payload is too large.\nexpected: %s\nreceived: %+v", - expectedErr, err) - } -} - -// Error path: tests that DecodeSizedBroadcast returns an error when the length -// of the data is shorter than the minimum length of a sized broadcast. -func TestDecodeSizedBroadcast_DataTooShortError(t *testing.T) { - data := []byte{0} - expectedErr := fmt.Sprintf( - errDecodeSizedBroadcastDataLen, len(data), sizedBroadcastMinSize) - - _, err := DecodeSizedBroadcast(data) - if err == nil || err.Error() != expectedErr { - t.Errorf("DecodeSizedBroadcast did not return the expected error "+ - "when the data is too small.\nexpected: %s\nreceived: %+v", - expectedErr, err) - } -} - -// Error path: tests that DecodeSizedBroadcast returns an error when the payload -// size is larger than the actual payload contained in the data. -func TestDecodeSizedBroadcast_SizeMismatchError(t *testing.T) { - data := []byte{255, 0, 10} - expectedErr := fmt.Sprintf( - errDecodeSizedBroadcastSize, data[0], len(data[sizeSize:])) - - _, err := DecodeSizedBroadcast(data) - if err == nil || err.Error() != expectedErr { - t.Errorf("DecodeSizedBroadcast did not return the expected error "+ - "when the size is too large.\nexpected: %s\nreceived: %+v", - expectedErr, err) - } -} - -// Tests that MaxSizedBroadcastPayloadSize returns the correct max size. -func TestMaxSizedBroadcastPayloadSize(t *testing.T) { - maxPayloadSize := 512 - expectedSize := maxPayloadSize - sizedBroadcastMinSize - receivedSize := MaxSizedBroadcastPayloadSize(maxPayloadSize) - if receivedSize != expectedSize { - t.Errorf("Incorrect max paylaod size.\nexpected: %d\nreceived: %d", - expectedSize, receivedSize) - } -} diff --git a/broadcast/symmetric.go b/broadcast/symmetric.go index cdd881e3e1febb38e2d2a1e924117c35ada699b4..89fceeccb34b63db968203848ecdf5b49f553a5b 100644 --- a/broadcast/symmetric.go +++ b/broadcast/symmetric.go @@ -31,14 +31,9 @@ const ( symmetricBroadcastServiceTag = "SymmetricBroadcast" ) -// MaxSymmetricPayloadSize returns the maximum size for a broadcasted payload. -func (bc *broadcastClient) maxSymmetricPayload() int { - return bc.net.GetMaxMessageLength() -} - // Broadcast broadcasts a payload over a symmetric channel. // Network must be healthy to send -// Requires a payload of size bc.MaxSymmetricPayloadSize() +// Requires a payload of size bc.MaxSymmetricPayloadSize() or smaller func (bc *broadcastClient) Broadcast(payload []byte, cMixParams cmix.CMIXParams) ( rounds.Round, ephemeral.Id, error) { assemble := func(rid id.Round) ([]byte, error) { @@ -51,7 +46,7 @@ func (bc *broadcastClient) Broadcast(payload []byte, cMixParams cmix.CMIXParams) // a payload assembled after the round is selected, allowing the round // info to be included in the payload. // Network must be healthy to send -// Requires a payload of size bc.MaxSymmetricPayloadSize() +// Requires a payload of size bc.MaxSymmetricPayloadSize() or smaller func (bc *broadcastClient) BroadcastWithAssembler(assembler Assembler, cMixParams cmix.CMIXParams) ( rounds.Round, ephemeral.Id, error) { if !bc.net.IsHealthy() { @@ -75,7 +70,12 @@ func (bc *broadcastClient) BroadcastWithAssembler(assembler Assembler, cMixParam // Encrypt payload rng := bc.rng.GetStream() defer rng.Close() - encryptedPayload, mac, fp = bc.channel.EncryptSymmetric(payload, rng) + encryptedPayload, mac, fp, err = bc.channel.EncryptSymmetric(payload, + bc.net.GetMaxMessageLength(), rng) + if err != nil { + return format.Fingerprint{}, message.Service{}, + nil, nil, err + } // Create service using symmetric broadcast service tag & channel reception ID // Allows anybody with this info to listen for messages on this channel diff --git a/broadcast/symmetric_test.go b/broadcast/symmetric_test.go index dfb73fbbf2ae7be65acafeedafc72147c85d5e45..3386a71ead8fb2ffada89329017975216be91507 100644 --- a/broadcast/symmetric_test.go +++ b/broadcast/symmetric_test.go @@ -7,6 +7,7 @@ package broadcast +/* import ( "bytes" "fmt" @@ -14,10 +15,9 @@ import ( "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" crypto "gitlab.com/elixxir/crypto/broadcast" - cMixCrypto "gitlab.com/elixxir/crypto/cmix" + "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/xx_network/crypto/csprng" - "gitlab.com/xx_network/crypto/signature/rsa" "reflect" "sync" "testing" @@ -38,19 +38,10 @@ func Test_symmetricClient_Smoke(t *testing.T) { rngGen := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG) cname := "MyChannel" cdesc := "This is my channel about stuff." - csalt := cMixCrypto.NewSalt(csprng.NewSystemRNG(), 32) - cpubkey := newRsaPubKey(64, t) - cid, err := crypto.NewChannelID(cname, cdesc, csalt, rsa.CreatePublicKeyPem(cpubkey)) - if err != nil { - t.Errorf("Failed to create channel ID: %+v", err) - } - channel := &crypto.Channel{ - ReceptionID: cid, - Name: cname, - Description: cdesc, - Salt: csalt, - RsaPubKey: cpubkey, - } + mCmix := newMockCmix(cMixHandler) + channel,_,_ := crypto.NewChannel(cname, cdesc, + mCmix.GetMaxMessageLength(), + rngGen.GetStream()) // Set up callbacks, callback channels, and the symmetric clients const n = 5 @@ -85,7 +76,7 @@ func Test_symmetricClient_Smoke(t *testing.T) { // Send broadcast from each client for i := range clients { - payload := make([]byte, newMockCmix(cMixHandler).GetMaxMessageLength()) + payload := make([]byte, clients[i].MaxPayloadSize()) copy(payload, fmt.Sprintf("Hello from client %d of %d.", i, len(clients))) @@ -142,10 +133,10 @@ func Test_symmetricClient_Smoke(t *testing.T) { } // Broadcast payload - _, _, err = clients[0].Broadcast(payload, cmix.GetDefaultCMIXParams()) + _, _, err := clients[0].Broadcast(payload, cmix.GetDefaultCMIXParams()) if err != nil { t.Errorf("Cmix 0 failed to send broadcast: %+v", err) } wg.Wait() -} +}*/ diff --git a/broadcast/utils_test.go b/broadcast/utils_test.go index 967cdb86947b4d9c87c8b0cca275a63d94ee5a7f..ee1dfebc264c208e037bcbd45385bac6160fa154 100644 --- a/broadcast/utils_test.go +++ b/broadcast/utils_test.go @@ -8,12 +8,9 @@ package broadcast import ( - "math/rand" "sync" - "testing" "time" - "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" @@ -24,19 +21,8 @@ import ( "gitlab.com/elixxir/primitives/format" ) -// newRsaPubKey generates a new random RSA public key for testing. -func newRsaPubKey(seed int64, t *testing.T) *rsa.PublicKey { - prng := rand.New(rand.NewSource(seed)) - privKey, err := rsa.GenerateKey(prng, 64) - if err != nil { - t.Errorf("Failed to generate new RSA key: %+v", err) - } - - return privKey.GetPublic() -} - //////////////////////////////////////////////////////////////////////////////// -// Mock cMix // +// Mock cMix // //////////////////////////////////////////////////////////////////////////////// type mockCmixHandler struct { @@ -58,7 +44,7 @@ type mockCmix struct { func newMockCmix(handler *mockCmixHandler) *mockCmix { return &mockCmix{ - numPrimeBytes: 4096, + numPrimeBytes: 4096 / 8, health: true, handler: handler, } @@ -68,8 +54,9 @@ func (m *mockCmix) GetMaxMessageLength() int { return format.NewMessage(m.numPrimeBytes).ContentsSize() } -func (m *mockCmix) SendWithAssembler(recipient *id.ID, assembler cmix.MessageAssembler, - cmixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) { +func (m *mockCmix) SendWithAssembler(recipient *id.ID, + assembler cmix.MessageAssembler, _ cmix.CMIXParams) ( + rounds.Round, ephemeral.Id, error) { fingerprint, service, payload, mac, err := assembler(42) if err != nil { diff --git a/channels/adminListener.go b/channels/adminListener.go index 0b26859d97f51c953ed543fad52cf14bd39d9483..1c53be04bd0b33f0feb79675dcd3dbb62a32d272 100644 --- a/channels/adminListener.go +++ b/channels/adminListener.go @@ -10,7 +10,6 @@ package channels import ( "github.com/golang/protobuf/proto" jww "github.com/spf13/jwalterweatherman" - "gitlab.com/elixxir/client/broadcast" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/crypto/channel" @@ -28,21 +27,12 @@ type adminListener struct { // Listen is called when a message is received for the admin listener func (al *adminListener) Listen(payload []byte, receptionID receptionID.EphemeralIdentity, round rounds.Round) { - - // Remove the padding - payloadUnpadded, err := broadcast.DecodeSizedBroadcast(payload) - if err != nil { - jww.WARN.Printf( - "Failed to strip the padding on User Message on channel %s", al.chID) - return - } - // Get the message ID - msgID := channel.MakeMessageID(payloadUnpadded) + msgID := channel.MakeMessageID(payload) // Decode the message as a channel message cm := &ChannelMessage{} - if err = proto.Unmarshal(payloadUnpadded, cm); err != nil { + if err := proto.Unmarshal(payload, cm); err != nil { jww.WARN.Printf("Failed to unmarshal Channel Message from Admin on "+ "channel %s", al.chID) return diff --git a/channels/adminListener_test.go b/channels/adminListener_test.go index c3414b673711bc5d4329aa458f35d7e7072c4dbe..e32f7b0eb59065797d8fe73591c94089ce9a18a7 100644 --- a/channels/adminListener_test.go +++ b/channels/adminListener_test.go @@ -9,7 +9,6 @@ package channels import ( "bytes" - "gitlab.com/elixxir/client/broadcast" "testing" "time" @@ -67,12 +66,6 @@ func TestAdminListener_Listen(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - chMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, cmSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - msgID := cryptoChannel.MakeMessageID(cmSerial) // Build the listener @@ -85,7 +78,7 @@ func TestAdminListener_Listen(t *testing.T) { } // Call the listener - al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(cmSerial, receptionID.EphemeralIdentity{}, r) // Check the results if !dummy.gotData { @@ -136,12 +129,6 @@ func TestAdminListener_Listen_BadRound(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - chMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, cmSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - // Build the listener dummy := &triggerAdminEventDummy{} @@ -152,7 +139,7 @@ func TestAdminListener_Listen_BadRound(t *testing.T) { } // Call the listener - al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(cmSerial, receptionID.EphemeralIdentity{}, r) // check the results if dummy.gotData { @@ -174,12 +161,6 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) { cmSerial := []byte("blarg") - chMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, cmSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - // Build the listener dummy := &triggerAdminEventDummy{} @@ -190,7 +171,7 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) { } // Call the listener - al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(cmSerial, receptionID.EphemeralIdentity{}, r) // Check the results if dummy.gotData { @@ -224,14 +205,8 @@ func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - chMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, cmSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - // Remove half the sized broadcast to make it malformed - chMsgSerialSized = chMsgSerialSized[:broadcast.GetSizedBroadcastSize(chMsgSerialSized)/2] + chMsgSerialSized := cmSerial[:len(cmSerial)/2] // Build the listener dummy := &triggerAdminEventDummy{} diff --git a/channels/interface.go b/channels/interface.go index 01e4066032f88a52fa9a1e3d118caf799e0beba8..622ee68029ef74a87fd666c3d3a14d6815b72672 100644 --- a/channels/interface.go +++ b/channels/interface.go @@ -12,7 +12,7 @@ import ( "gitlab.com/elixxir/client/cmix/rounds" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" cryptoChannel "gitlab.com/elixxir/crypto/channel" - "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/elixxir/crypto/rsa" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" "math" @@ -51,7 +51,7 @@ type Manager interface { // should be wrapped in a function which defines the wire protocol // If the final message, before being sent over the wire, is too long, this will // return an error. The message must be at most 510 bytes long. - SendAdminGeneric(privKey *rsa.PrivateKey, channelID *id.ID, + SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID, messageType MessageType, msg []byte, validUntil time.Duration, params cmix.CMIXParams) (cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) diff --git a/channels/joinedChannel.go b/channels/joinedChannel.go index 8d41a47c7e404aab79e76b5788c65c86f14b11a9..f3ff927bd0a9249df2ffd5fec246b00d63aef3aa 100644 --- a/channels/joinedChannel.go +++ b/channels/joinedChannel.go @@ -124,7 +124,7 @@ func (m *manager) addChannel(channel *cryptoBroadcast.Channel) error { chID: channel.ReceptionID, trigger: m.events.triggerAdminEvent, checkSent: m.st.MessageReceive, - }).Listen, broadcast.Asymmetric) + }).Listen, broadcast.RSAToPublic) if err != nil { return err } @@ -264,7 +264,7 @@ func initBroadcast(c *cryptoBroadcast.Channel, chID: c.ReceptionID, trigger: e.triggerAdminEvent, checkSent: mr, - }).Listen, broadcast.Asymmetric) + }).Listen, broadcast.RSAToPublic) if err != nil { return nil, err } diff --git a/channels/joinedChannel_test.go b/channels/joinedChannel_test.go index 1d4750deb0eeddb9adbcfe5dd5c6189e50e19f83..2da31d171d058fa5b8ab67165004abee4a04bd13 100644 --- a/channels/joinedChannel_test.go +++ b/channels/joinedChannel_test.go @@ -17,11 +17,10 @@ import ( "gitlab.com/elixxir/client/storage/versioned" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" cryptoChannel "gitlab.com/elixxir/crypto/channel" - "gitlab.com/elixxir/crypto/cmix" "gitlab.com/elixxir/crypto/fastRNG" + "gitlab.com/elixxir/crypto/rsa" "gitlab.com/elixxir/ekv" "gitlab.com/xx_network/crypto/csprng" - "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" "reflect" @@ -446,29 +445,9 @@ func Test_makeJoinedChannelKey_Consistency(t *testing.T) { // cryptoBroadcast.NewChannel does but with a smaller RSA key and salt to make // tests run quicker. func newTestChannel(name, description string, rng csprng.Source) ( - *cryptoBroadcast.Channel, *rsa.PrivateKey, error) { - // Uses 128 bits instead of 4096 bits - pk, err := rsa.GenerateKey(rng, 128) - if err != nil { - return nil, nil, err - } - - // Uses 16 bits instead of 512 bits - salt := cmix.NewSalt(rng, 16) - - channelID, err := cryptoBroadcast.NewChannelID( - name, description, salt, rsa.CreatePublicKeyPem(pk.GetPublic())) - if err != nil { - return nil, nil, err - } - - return &cryptoBroadcast.Channel{ - ReceptionID: channelID, - Name: name, - Description: description, - Salt: salt, - RsaPubKey: pk.GetPublic(), - }, pk, nil + *cryptoBroadcast.Channel, rsa.PrivateKey, error) { + c, pk, err := cryptoBroadcast.NewChannelVariableKeyUnsafe(name, description, 1000, 512, rng) + return c, pk, err } //////////////////////////////////////////////////////////////////////////////// diff --git a/channels/send.go b/channels/send.go index 86c6b92e24b2c2d10c2a99c8b92328a36e7eb4d2..978c66e925d79691c9a6986c57b084f1ac99f70e 100644 --- a/channels/send.go +++ b/channels/send.go @@ -8,11 +8,10 @@ package channels import ( - "gitlab.com/elixxir/client/broadcast" "gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix/rounds" cryptoChannel "gitlab.com/elixxir/crypto/channel" - "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/elixxir/crypto/rsa" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" "google.golang.org/protobuf/proto" @@ -90,14 +89,7 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, return nil, err } - //Fill in any extra bits in the payload to ensure it is the right size - usrMsgSerialSized, err := broadcast.NewSizedBroadcast( - ch.broadcast.MaxAsymmetricPayloadSize(), usrMsgSerial) - if err != nil { - return nil, err - } - - return usrMsgSerialSized, nil + return usrMsgSerial, nil } r, ephid, err := ch.broadcast.BroadcastWithAssembler(assemble, params) @@ -117,7 +109,7 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, // should be wrapped in a function which defines the wire protocol // If the final message, before being sent over the wire, is too long, this will // return an error. The message must be at most 510 bytes long. -func (m *manager) SendAdminGeneric(privKey *rsa.PrivateKey, channelID *id.ID, +func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID, messageType MessageType, msg []byte, validUntil time.Duration, params cmix.CMIXParams) (cryptoChannel.MessageID, rounds.Round, ephemeral.Id, error) { @@ -128,12 +120,6 @@ func (m *manager) SendAdminGeneric(privKey *rsa.PrivateKey, channelID *id.ID, return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err } - //verify the private key is correct - if ch.broadcast.Get().RsaPubKey.N.Cmp(privKey.GetPublic().N) != 0 { - return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, - WrongPrivateKey - } - var msgId cryptoChannel.MessageID var chMsg *ChannelMessage //Note: we are not checking check if message is too long before trying to @@ -159,21 +145,14 @@ func (m *manager) SendAdminGeneric(privKey *rsa.PrivateKey, channelID *id.ID, msgId = cryptoChannel.MakeMessageID(chMsgSerial) //check if the message is too long - if len(chMsgSerial) > broadcast.MaxSizedBroadcastPayloadSize(privKey.Size()) { + if len(chMsgSerial) > ch.broadcast.MaxRSAToPublicPayloadSize() { return nil, MessageTooLongErr } - //Fill in any extra bits in the payload to ensure it is the right size - chMsgSerialSized, err := broadcast.NewSizedBroadcast( - ch.broadcast.MaxAsymmetricPayloadSize(), chMsgSerial) - if err != nil { - return nil, err - } - - return chMsgSerialSized, nil + return chMsgSerial, nil } - r, ephid, err := ch.broadcast.BroadcastAsymmetricWithAssembler(privKey, + r, ephid, err := ch.broadcast.BroadcastRSAToPublicWithAssembler(privKey, assemble, params) m.st.sendAdmin(channelID, chMsg, msgId, r) diff --git a/channels/send_test.go b/channels/send_test.go index 2e2985ccaf12f6bd6c843486bf07d48f3b65c76b..5a6e1999c37be4394680c56b02ebbd09e4717411 100644 --- a/channels/send_test.go +++ b/channels/send_test.go @@ -15,12 +15,12 @@ import ( "gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/client/storage/versioned" cryptoChannel "gitlab.com/elixxir/crypto/channel" + "gitlab.com/elixxir/crypto/rsa" "gitlab.com/elixxir/ekv" "gitlab.com/xx_network/crypto/csprng" "testing" "time" - "gitlab.com/xx_network/crypto/multicastRSA" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id/ephemeral" @@ -37,7 +37,7 @@ type mockBroadcastChannel struct { payload []byte params cmix.CMIXParams - pk multicastRSA.PrivateKey + pk rsa.PrivateKey crypto *cryptoBroadcast.Channel } @@ -46,7 +46,7 @@ func (m *mockBroadcastChannel) MaxPayloadSize() int { return 1024 } -func (m *mockBroadcastChannel) MaxAsymmetricPayloadSize() int { +func (m *mockBroadcastChannel) MaxRSAToPublicPayloadSize() int { return 512 } @@ -77,7 +77,7 @@ func (m *mockBroadcastChannel) BroadcastWithAssembler(assembler broadcast.Assemb return rounds.Round{ID: 123}, ephemeral.Id{}, err } -func (m *mockBroadcastChannel) BroadcastAsymmetric(pk multicastRSA.PrivateKey, payload []byte, +func (m *mockBroadcastChannel) BroadcastRSAtoPublic(pk rsa.PrivateKey, payload []byte, cMixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) { m.hasRun = true @@ -88,8 +88,8 @@ func (m *mockBroadcastChannel) BroadcastAsymmetric(pk multicastRSA.PrivateKey, p return rounds.Round{ID: 123}, ephemeral.Id{}, nil } -func (m *mockBroadcastChannel) BroadcastAsymmetricWithAssembler( - pk multicastRSA.PrivateKey, assembler broadcast.Assembler, +func (m *mockBroadcastChannel) BroadcastRSAToPublicWithAssembler( + pk rsa.PrivateKey, assembler broadcast.Assembler, cMixParams cmix.CMIXParams) (rounds.Round, ephemeral.Id, error) { m.hasRun = true @@ -181,14 +181,8 @@ func TestSendGeneric(t *testing.T) { //verify the message was handled correctly - //Unsize the broadcast - unsized, err := broadcast.DecodeSizedBroadcast(mbc.payload) - if err != nil { - t.Fatalf("Failed to decode the sized broadcast: %s", err) - } - //decode the user message - umi, err := unmarshalUserMessageInternal(unsized) + umi, err := unmarshalUserMessageInternal(mbc.payload) if err != nil { t.Fatalf("Failed to decode the user message: %s", err) } @@ -240,7 +234,8 @@ func TestAdminGeneric(t *testing.T) { validUntil := time.Hour rng := &csprng.SystemRNG{} - ch, priv, err := cryptoBroadcast.NewChannel("test", "test", rng) + ch, priv, err := cryptoBroadcast.NewChannel("test", "test", + 1000, rng) if err != nil { t.Fatalf("Failed to generate channel: %+v", err) } @@ -260,13 +255,7 @@ func TestAdminGeneric(t *testing.T) { //verify the message was handled correctly - //Unsize the broadcast - unsized, err := broadcast.DecodeSizedBroadcast(mbc.payload) - if err != nil { - t.Fatalf("Failed to decode the sized broadcast: %s", err) - } - - msgID := cryptoChannel.MakeMessageID(unsized) + msgID := cryptoChannel.MakeMessageID(mbc.payload) if !msgID.Equals(messageId) { t.Errorf("The message IDs do not match. %s vs %s ", @@ -275,7 +264,7 @@ func TestAdminGeneric(t *testing.T) { //decode the channel message chMgs := &ChannelMessage{} - err = proto.Unmarshal(unsized, chMgs) + err = proto.Unmarshal(mbc.payload, chMgs) if err != nil { t.Fatalf("Failed to decode the channel message: %s", err) } @@ -339,14 +328,8 @@ func TestSendMessage(t *testing.T) { //verify the message was handled correctly - //Unsize the broadcast - unsized, err := broadcast.DecodeSizedBroadcast(mbc.payload) - if err != nil { - t.Fatalf("Failed to decode the sized broadcast: %s", err) - } - //decode the user message - umi, err := unmarshalUserMessageInternal(unsized) + umi, err := unmarshalUserMessageInternal(mbc.payload) if err != nil { t.Fatalf("Failed to decode the user message: %s", err) } @@ -427,14 +410,8 @@ func TestSendReply(t *testing.T) { //verify the message was handled correctly - //Unsize the broadcast - unsized, err := broadcast.DecodeSizedBroadcast(mbc.payload) - if err != nil { - t.Fatalf("Failed to decode the sized broadcast: %s", err) - } - //decode the user message - umi, err := unmarshalUserMessageInternal(unsized) + umi, err := unmarshalUserMessageInternal(mbc.payload) if err != nil { t.Fatalf("Failed to decode the user message: %s", err) } @@ -514,14 +491,8 @@ func TestSendReaction(t *testing.T) { //verify the message was handled correctly - //Unsize the broadcast - unsized, err := broadcast.DecodeSizedBroadcast(mbc.payload) - if err != nil { - t.Fatalf("Failed to decode the sized broadcast: %s", err) - } - //decode the user message - umi, err := unmarshalUserMessageInternal(unsized) + umi, err := unmarshalUserMessageInternal(mbc.payload) if err != nil { t.Fatalf("Failed to decode the user message: %s", err) } diff --git a/channels/userListener.go b/channels/userListener.go index 227afb742a189d84c38cb2f0cf9cdb43747ba159..575c05e54d5810a717610fff64b7b81ad754bc99 100644 --- a/channels/userListener.go +++ b/channels/userListener.go @@ -10,7 +10,6 @@ package channels import ( "crypto/ed25519" jww "github.com/spf13/jwalterweatherman" - "gitlab.com/elixxir/client/broadcast" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/primitives/states" @@ -31,16 +30,8 @@ type userListener struct { func (ul *userListener) Listen(payload []byte, receptionID receptionID.EphemeralIdentity, round rounds.Round) { - //Remove the padding - payloadUnpadded, err := broadcast.DecodeSizedBroadcast(payload) - if err != nil { - jww.WARN.Printf("Failed to strip the padding on User Message "+ - "on channel %s", ul.chID) - return - } - //Decode the message as a user message - umi, err := unmarshalUserMessageInternal(payloadUnpadded) + umi, err := unmarshalUserMessageInternal(payload) if err != nil { jww.WARN.Printf("Failed to unmarshal User Message on "+ "channel %s", ul.chID) diff --git a/channels/userListener_test.go b/channels/userListener_test.go index fcf69fbffd92cf60e1098fbc40a5924e8c1abeeb..d58d540ffb84a96980fcf4868c1838eda4025763 100644 --- a/channels/userListener_test.go +++ b/channels/userListener_test.go @@ -16,7 +16,6 @@ import ( "github.com/golang/protobuf/proto" - "gitlab.com/elixxir/client/broadcast" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" cryptoChannel "gitlab.com/elixxir/crypto/channel" @@ -92,12 +91,6 @@ func TestUserListener_Listen(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - umMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, umSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - //build the listener dummy := &triggerEventDummy{} @@ -109,7 +102,7 @@ func TestUserListener_Listen(t *testing.T) { } //call the listener - al.Listen(umMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(umSerial, receptionID.EphemeralIdentity{}, r) //check the results if !dummy.gotData { @@ -186,12 +179,6 @@ func TestUserListener_Listen_BadUserSig(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - umMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, umSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - //build the listener dummy := &triggerEventDummy{} @@ -203,7 +190,7 @@ func TestUserListener_Listen_BadUserSig(t *testing.T) { } //call the listener - al.Listen(umMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(umSerial, receptionID.EphemeralIdentity{}, r) //check the results if dummy.gotData { @@ -258,12 +245,6 @@ func TestUserListener_Listen_BadValidSig(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - umMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, umSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - //build the listener dummy := &triggerEventDummy{} @@ -275,7 +256,7 @@ func TestUserListener_Listen_BadValidSig(t *testing.T) { } //call the listener - al.Listen(umMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(umSerial, receptionID.EphemeralIdentity{}, r) //check the results if dummy.gotData { @@ -329,12 +310,6 @@ func TestUserListener_Listen_BadUnameTs(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - umMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, umSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - //build the listener dummy := &triggerEventDummy{} @@ -346,7 +321,7 @@ func TestUserListener_Listen_BadUnameTs(t *testing.T) { } //call the listener - al.Listen(umMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(umSerial, receptionID.EphemeralIdentity{}, r) //check the results if dummy.gotData { @@ -401,12 +376,6 @@ func TestUserListener_Listen_BadRound(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - umMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, umSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - //build the listener dummy := &triggerEventDummy{} @@ -418,7 +387,7 @@ func TestUserListener_Listen_BadRound(t *testing.T) { } //call the listener - al.Listen(umMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(umSerial, receptionID.EphemeralIdentity{}, r) //check the results if dummy.gotData { @@ -440,12 +409,6 @@ func TestUserListener_Listen_BadMessage(t *testing.T) { umSerial := []byte("malformed") - umMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, umSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - //build the listener dummy := &triggerEventDummy{} @@ -457,7 +420,7 @@ func TestUserListener_Listen_BadMessage(t *testing.T) { } //call the listener - al.Listen(umMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(umSerial, receptionID.EphemeralIdentity{}, r) //check the results if dummy.gotData { @@ -511,14 +474,8 @@ func TestUserListener_Listen_BadSizedBroadcast(t *testing.T) { t.Fatalf("Failed to marshal proto: %+v", err) } - umMsgSerialSized, err := broadcast.NewSizedBroadcast( - 512, umSerial) - if err != nil { - t.Fatalf("Failed to size channel message: %+v", err) - } - //remove half the sized broadcast to make it malformed - umMsgSerialSized = umMsgSerialSized[:broadcast.GetSizedBroadcastSize(umMsgSerialSized)/2] + umSerial = umSerial[:len(umSerial)/2] //build the listener dummy := &triggerEventDummy{} @@ -531,7 +488,7 @@ func TestUserListener_Listen_BadSizedBroadcast(t *testing.T) { } //call the listener - al.Listen(umMsgSerialSized, receptionID.EphemeralIdentity{}, r) + al.Listen(umSerial, receptionID.EphemeralIdentity{}, r) //check the results if dummy.gotData { diff --git a/cmd/broadcast.go b/cmd/broadcast.go index 15c01a99b3397ce4708eaba29021f7cc1f0c21e7..7b0e7c9183ae1311bf7f2478640309723ca824e4 100644 --- a/cmd/broadcast.go +++ b/cmd/broadcast.go @@ -20,7 +20,7 @@ import ( "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" crypto "gitlab.com/elixxir/crypto/broadcast" - "gitlab.com/xx_network/crypto/signature/rsa" + rsa2 "gitlab.com/elixxir/crypto/rsa" "gitlab.com/xx_network/primitives/utils" "sync" ) @@ -56,7 +56,7 @@ var broadcastCmd = &cobra.Command{ waitUntilConnected(connected) /* Set up underlying crypto broadcast.Channel */ var channel *crypto.Channel - var pk *rsa.PrivateKey + var pk rsa2.PrivateKey keyPath := viper.GetString(broadcastKeyPathFlag) path, err := utils.ExpandPath(viper.GetString(broadcastChanPathFlag)) if utils.Exists(path) { @@ -81,23 +81,25 @@ var broadcastCmd = &cobra.Command{ if viper.GetBool(broadcastNewFlag) { // Create a new broadcast channel - channel, pk, err = crypto.NewChannel(name, desc, user.GetRng().GetStream()) + channel, pk, err = crypto.NewChannel(name, desc, user.GetCmix().GetMaxMessageLength(), user.GetRng().GetStream()) if err != nil { jww.FATAL.Panicf("Failed to create new channel: %+v", err) } if keyPath != "" { - err = utils.WriteFile(keyPath, rsa.CreatePrivateKeyPem(pk), os.ModePerm, os.ModeDir) + err = utils.WriteFile(keyPath, pk.MarshalPem(), os.ModePerm, os.ModeDir) if err != nil { jww.ERROR.Printf("Failed to write private key to path %s: %+v", path, err) } } else { - fmt.Printf("Private key generated for channel: %+v", rsa.CreatePrivateKeyPem(pk)) + fmt.Printf("Private key generated for channel: %+v", pk.MarshalPem()) } fmt.Printf("New broadcast channel generated") } else { + //fixme: redo channels, should be using pretty print over cli + // Read rest of info from config & build object manually - pubKeyBytes := []byte(viper.GetString(broadcastRsaPubFlag)) + /*pubKeyBytes := []byte(viper.GetString(broadcastRsaPubFlag)) pubKey, err := rsa.LoadPublicKeyFromPem(pubKeyBytes) if err != nil { jww.FATAL.Panicf("Failed to load public key at path: %+v", err) @@ -115,7 +117,7 @@ var broadcastCmd = &cobra.Command{ Description: desc, Salt: salt, RsaPubKey: pubKey, - } + }*/ } // Save channel to disk @@ -142,7 +144,8 @@ var broadcastCmd = &cobra.Command{ if err != nil { jww.ERROR.Printf("Failed to read private key from %s: %+v", ep, err) } - pk, err = rsa.LoadPrivateKeyFromPem(keyBytes) + + pk, err = rsa2.GetScheme().UnmarshalPrivateKeyPEM(keyBytes) if err != nil { jww.ERROR.Printf("Failed to load private key %+v: %+v", keyBytes, err) } @@ -179,7 +182,7 @@ var broadcastCmd = &cobra.Command{ jww.INFO.Printf("Received asymmetric message from %s over round %d", receptionID, round.ID) asymmetricReceiveChan <- payload } - err = bcl.RegisterListener(acb, broadcast.Asymmetric) + err = bcl.RegisterListener(acb, broadcast.RSAToPublic) if err != nil { jww.FATAL.Panicf("Failed to register asymmetric listener: %+v", err) } @@ -205,12 +208,7 @@ var broadcastCmd = &cobra.Command{ /* Send symmetric broadcast */ if symmetric != "" { - // Create properly sized broadcast message - broadcastMessage, err := broadcast.NewSizedBroadcast(bcl.MaxPayloadSize(), []byte(symmetric)) - if err != nil { - jww.FATAL.Panicf("Failed to create sized broadcast: %+v", err) - } - rid, eid, err := bcl.Broadcast(broadcastMessage, cmix.GetDefaultCMIXParams()) + rid, eid, err := bcl.Broadcast([]byte(symmetric), cmix.GetDefaultCMIXParams()) if err != nil { jww.ERROR.Printf("Failed to send symmetric broadcast message: %+v", err) retries++ @@ -223,14 +221,10 @@ var broadcastCmd = &cobra.Command{ /* Send asymmetric broadcast */ if asymmetric != "" { // Create properly sized broadcast message - broadcastMessage, err := broadcast.NewSizedBroadcast(bcl.MaxAsymmetricPayloadSize(), []byte(asymmetric)) - if err != nil { - jww.FATAL.Panicf("Failed to create sized broadcast: %+v", err) - } if pk == nil { jww.FATAL.Panicf("CANNOT SEND ASYMMETRIC BROADCAST WITHOUT PRIVATE KEY") } - rid, eid, err := bcl.BroadcastAsymmetric(pk, broadcastMessage, cmix.GetDefaultCMIXParams()) + rid, eid, err := bcl.BroadcastRSAtoPublic(pk, []byte(asymmetric), cmix.GetDefaultCMIXParams()) if err != nil { jww.ERROR.Printf("Failed to send asymmetric broadcast message: %+v", err) retries++ @@ -261,23 +255,13 @@ var broadcastCmd = &cobra.Command{ select { case receivedPayload := <-asymmetricReceiveChan: receivedCount++ - receivedBroadcast, err := broadcast.DecodeSizedBroadcast(receivedPayload) - if err != nil { - jww.ERROR.Printf("Failed to decode sized broadcast: %+v", err) - continue - } - fmt.Printf("Asymmetric broadcast message received: %s\n", string(receivedBroadcast)) + fmt.Printf("Asymmetric broadcast message received: %s\n", string(receivedPayload)) if receivedCount == expectedCnt { done = true } case receivedPayload := <-receiveChan: receivedCount++ - receivedBroadcast, err := broadcast.DecodeSizedBroadcast(receivedPayload) - if err != nil { - jww.ERROR.Printf("Failed to decode sized broadcast: %+v", err) - continue - } - fmt.Printf("Symmetric broadcast message received: %s\n", string(receivedBroadcast)) + fmt.Printf("Symmetric broadcast message received: %s\n", string(receivedPayload)) if receivedCount == expectedCnt { done = true } diff --git a/go.mod b/go.mod index 060e8f3a08ea424383c21e1ad221d2634e00e8ca..9ae5d293a28e75f720e602688149c0f011bf6ed2 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/stretchr/testify v1.8.0 gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f gitlab.com/elixxir/comms v0.0.4-0.20220913220502-eed192f654bd - gitlab.com/elixxir/crypto v0.0.7-0.20220913220142-ab0771bad0af + gitlab.com/elixxir/crypto v0.0.7-0.20220919174648-8d1b7f5cacc4 gitlab.com/elixxir/ekv v0.2.1 gitlab.com/elixxir/primitives v0.0.3-0.20220901220638-1acc75fabdc6 gitlab.com/xx_network/comms v0.0.4-0.20220913215811-c4bf83b27de3 diff --git a/go.sum b/go.sum index 1a159e20639d8254167e431e61db4d30ec922634..fe9874ef3c78d9e1734ce774e87408df3ca997b2 100644 --- a/go.sum +++ b/go.sum @@ -635,6 +635,18 @@ gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA= gitlab.com/elixxir/crypto v0.0.7-0.20220913220142-ab0771bad0af h1:L1eOTS6m8dlCheAFOf/S3C+IcORd2R8f5qdyVRVelWA= gitlab.com/elixxir/crypto v0.0.7-0.20220913220142-ab0771bad0af/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= +gitlab.com/elixxir/crypto v0.0.7-0.20220917193938-d5d45ca0a4d2 h1:AKmjX9Az2ArBT1HFO2rPeDX2hdpSo6/wtUEdff/ybck= +gitlab.com/elixxir/crypto v0.0.7-0.20220917193938-d5d45ca0a4d2/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= +gitlab.com/elixxir/crypto v0.0.7-0.20220917204352-30b24e0711a2 h1:IK2ZUkvDn4+/1fnXH2TVxuacC8wzO+kgWs5mx/qBz7c= +gitlab.com/elixxir/crypto v0.0.7-0.20220917204352-30b24e0711a2/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= +gitlab.com/elixxir/crypto v0.0.7-0.20220917212457-088250d48a3c h1:cUPyHvh3kiyv442SHECVIMA2mMr/F8Y7kxAOnu4Gde4= +gitlab.com/elixxir/crypto v0.0.7-0.20220917212457-088250d48a3c/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= +gitlab.com/elixxir/crypto v0.0.7-0.20220919165806-fc1d25b4fd1d h1:mNqnjlfXZ3FOpr/kgRGuPZTqH59HEK4q/N6f59L7K8Q= +gitlab.com/elixxir/crypto v0.0.7-0.20220919165806-fc1d25b4fd1d/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= +gitlab.com/elixxir/crypto v0.0.7-0.20220919170559-538d10454d07 h1:zIUAxKXpGnAejPyv4S7yVX4Zw2bA1k1BW7m3oiTqa1Y= +gitlab.com/elixxir/crypto v0.0.7-0.20220919170559-538d10454d07/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= +gitlab.com/elixxir/crypto v0.0.7-0.20220919174648-8d1b7f5cacc4 h1:Gou55kAKhwWlK9hKFYAfOMrwgk04qpOsB5/tZa8OWlc= +gitlab.com/elixxir/crypto v0.0.7-0.20220919174648-8d1b7f5cacc4/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= gitlab.com/elixxir/ekv v0.2.1 h1:dtwbt6KmAXG2Tik5d60iDz2fLhoFBgWwST03p7T+9Is= gitlab.com/elixxir/ekv v0.2.1/go.mod h1:USLD7xeDnuZEavygdrgzNEwZXeLQJK/w1a+htpN+JEU= gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=