From dbaf622e1277fcddf4fed07e1f461b0c060d3f3b Mon Sep 17 00:00:00 2001 From: Adam Babik Date: Wed, 3 Jul 2019 21:13:11 +0200 Subject: [PATCH] Refactor messaging (#1510) This change flattens messaging/chat package. It also removes dependency between multidevice and chat/protobuf packages. The Publisher interface was also changed a bit to support more native types. Version got bumped to 0.29.0-beta.3. --- VERSION | 2 +- api/backend.go | 2 +- messaging/chat/chat.pb.go | 342 ------------------ messaging/chat/encryption.go | 8 +- .../chat/encryption_multi_device_test.go | 4 +- messaging/chat/encryption_test.go | 4 +- messaging/chat/persistence.go | 6 +- messaging/chat/protocol.go | 48 ++- messaging/chat/protocol_test.go | 4 +- messaging/chat/sql_lite_persistence.go | 16 +- messaging/chat/sql_lite_persistence_test.go | 4 +- messaging/{chat => }/crypto/crypto.go | 0 messaging/{chat => }/crypto/crypto_test.go | 0 .../{chat => }/crypto/ethereum_crypto.go | 3 +- messaging/{chat => }/db/db.go | 2 +- messaging/{chat => }/db/migrations/bindata.go | 0 messaging/filter/service.go | 2 +- messaging/filter/service_test.go | 7 +- .../{chat => }/multidevice/persistence.go | 0 messaging/{chat => }/multidevice/service.go | 36 +- .../multidevice/sql_lite_persistence.go | 0 .../multidevice/sql_lite_persistence_test.go | 4 +- messaging/publisher/publisher.go | 50 +-- messaging/publisher/publisher_test.go | 14 +- .../{chat => }/sharedsecret/persistence.go | 2 +- messaging/{chat => }/sharedsecret/service.go | 7 +- .../{chat => }/sharedsecret/service_test.go | 4 +- services/shhext/api.go | 25 +- {messaging/chat => services/shhext}/rpc.go | 2 +- services/shhext/service.go | 14 +- static/chat_db_migrations/static.go | 2 +- 31 files changed, 158 insertions(+), 456 deletions(-) delete mode 100644 messaging/chat/chat.pb.go rename messaging/{chat => }/crypto/crypto.go (100%) rename messaging/{chat => }/crypto/crypto_test.go (100%) rename messaging/{chat => }/crypto/ethereum_crypto.go (99%) rename messaging/{chat => }/db/db.go (98%) rename messaging/{chat => }/db/migrations/bindata.go (100%) rename messaging/{chat => }/multidevice/persistence.go (100%) rename messaging/{chat => }/multidevice/service.go (74%) rename messaging/{chat => }/multidevice/sql_lite_persistence.go (100%) rename messaging/{chat => }/multidevice/sql_lite_persistence_test.go (98%) rename messaging/{chat => }/sharedsecret/persistence.go (98%) rename messaging/{chat => }/sharedsecret/service.go (93%) rename messaging/{chat => }/sharedsecret/service_test.go (97%) rename {messaging/chat => services/shhext}/rpc.go (97%) diff --git a/VERSION b/VERSION index 443690c1d..ca3b989fa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.0-beta.2 +0.29.0-beta.3 diff --git a/api/backend.go b/api/backend.go index 5fb7cc91f..e352d09c8 100644 --- a/api/backend.go +++ b/api/backend.go @@ -19,7 +19,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/status-im/status-go/account" "github.com/status-im/status-go/mailserver/registry" - "github.com/status-im/status-go/messaging/chat/crypto" + "github.com/status-im/status-go/messaging/crypto" "github.com/status-im/status-go/node" "github.com/status-im/status-go/notifications/push/fcm" "github.com/status-im/status-go/params" diff --git a/messaging/chat/chat.pb.go b/messaging/chat/chat.pb.go deleted file mode 100644 index f0e18221a..000000000 --- a/messaging/chat/chat.pb.go +++ /dev/null @@ -1,342 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: chat.proto - -package chat - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// What is sent through the wire -type ChatMessagePayload struct { - // Message content - Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` - // MIME type - ContentType string `protobuf:"bytes,2,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` - // Message type - MessageType string `protobuf:"bytes,3,opt,name=message_type,json=messageType,proto3" json:"message_type,omitempty"` - // Sender's clock value for message ordering - ClockValue float64 `protobuf:"fixed64,4,opt,name=clock_value,json=clockValue,proto3" json:"clock_value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ChatMessagePayload) Reset() { *m = ChatMessagePayload{} } -func (m *ChatMessagePayload) String() string { return proto.CompactTextString(m) } -func (*ChatMessagePayload) ProtoMessage() {} -func (*ChatMessagePayload) Descriptor() ([]byte, []int) { - return fileDescriptor_8c585a45e2093e54, []int{0} -} - -func (m *ChatMessagePayload) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ChatMessagePayload.Unmarshal(m, b) -} -func (m *ChatMessagePayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ChatMessagePayload.Marshal(b, m, deterministic) -} -func (m *ChatMessagePayload) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChatMessagePayload.Merge(m, src) -} -func (m *ChatMessagePayload) XXX_Size() int { - return xxx_messageInfo_ChatMessagePayload.Size(m) -} -func (m *ChatMessagePayload) XXX_DiscardUnknown() { - xxx_messageInfo_ChatMessagePayload.DiscardUnknown(m) -} - -var xxx_messageInfo_ChatMessagePayload proto.InternalMessageInfo - -func (m *ChatMessagePayload) GetContent() string { - if m != nil { - return m.Content - } - return "" -} - -func (m *ChatMessagePayload) GetContentType() string { - if m != nil { - return m.ContentType - } - return "" -} - -func (m *ChatMessagePayload) GetMessageType() string { - if m != nil { - return m.MessageType - } - return "" -} - -func (m *ChatMessagePayload) GetClockValue() float64 { - if m != nil { - return m.ClockValue - } - return 0 -} - -// ContactUpdatePayload is sent when a user updates its profile -type ContactUpdatePayload struct { - // Contact display name - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Contact profile image, using the data URI scheme (e.g. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAA...") - ProfileImage string `protobuf:"bytes,2,opt,name=profile_image,json=profileImage,proto3" json:"profile_image,omitempty"` - // Contact address - Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` - // Contact Firebase Cloud Messaging token - FcmToken string `protobuf:"bytes,4,opt,name=fcm_token,json=fcmToken,proto3" json:"fcm_token,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ContactUpdatePayload) Reset() { *m = ContactUpdatePayload{} } -func (m *ContactUpdatePayload) String() string { return proto.CompactTextString(m) } -func (*ContactUpdatePayload) ProtoMessage() {} -func (*ContactUpdatePayload) Descriptor() ([]byte, []int) { - return fileDescriptor_8c585a45e2093e54, []int{1} -} - -func (m *ContactUpdatePayload) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ContactUpdatePayload.Unmarshal(m, b) -} -func (m *ContactUpdatePayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ContactUpdatePayload.Marshal(b, m, deterministic) -} -func (m *ContactUpdatePayload) XXX_Merge(src proto.Message) { - xxx_messageInfo_ContactUpdatePayload.Merge(m, src) -} -func (m *ContactUpdatePayload) XXX_Size() int { - return xxx_messageInfo_ContactUpdatePayload.Size(m) -} -func (m *ContactUpdatePayload) XXX_DiscardUnknown() { - xxx_messageInfo_ContactUpdatePayload.DiscardUnknown(m) -} - -var xxx_messageInfo_ContactUpdatePayload proto.InternalMessageInfo - -func (m *ContactUpdatePayload) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *ContactUpdatePayload) GetProfileImage() string { - if m != nil { - return m.ProfileImage - } - return "" -} - -func (m *ContactUpdatePayload) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func (m *ContactUpdatePayload) GetFcmToken() string { - if m != nil { - return m.FcmToken - } - return "" -} - -// Incoming RPC messages -type OneToOneRPC struct { - Src string `protobuf:"bytes,1,opt,name=src,proto3" json:"src,omitempty"` - Dst string `protobuf:"bytes,2,opt,name=dst,proto3" json:"dst,omitempty"` - Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *OneToOneRPC) Reset() { *m = OneToOneRPC{} } -func (m *OneToOneRPC) String() string { return proto.CompactTextString(m) } -func (*OneToOneRPC) ProtoMessage() {} -func (*OneToOneRPC) Descriptor() ([]byte, []int) { - return fileDescriptor_8c585a45e2093e54, []int{2} -} - -func (m *OneToOneRPC) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OneToOneRPC.Unmarshal(m, b) -} -func (m *OneToOneRPC) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OneToOneRPC.Marshal(b, m, deterministic) -} -func (m *OneToOneRPC) XXX_Merge(src proto.Message) { - xxx_messageInfo_OneToOneRPC.Merge(m, src) -} -func (m *OneToOneRPC) XXX_Size() int { - return xxx_messageInfo_OneToOneRPC.Size(m) -} -func (m *OneToOneRPC) XXX_DiscardUnknown() { - xxx_messageInfo_OneToOneRPC.DiscardUnknown(m) -} - -var xxx_messageInfo_OneToOneRPC proto.InternalMessageInfo - -func (m *OneToOneRPC) GetSrc() string { - if m != nil { - return m.Src - } - return "" -} - -func (m *OneToOneRPC) GetDst() string { - if m != nil { - return m.Dst - } - return "" -} - -func (m *OneToOneRPC) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -type ContactUpdateRPC struct { - Src string `protobuf:"bytes,1,opt,name=src,proto3" json:"src,omitempty"` - Dst string `protobuf:"bytes,2,opt,name=dst,proto3" json:"dst,omitempty"` - Payload *ContactUpdatePayload `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ContactUpdateRPC) Reset() { *m = ContactUpdateRPC{} } -func (m *ContactUpdateRPC) String() string { return proto.CompactTextString(m) } -func (*ContactUpdateRPC) ProtoMessage() {} -func (*ContactUpdateRPC) Descriptor() ([]byte, []int) { - return fileDescriptor_8c585a45e2093e54, []int{3} -} - -func (m *ContactUpdateRPC) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ContactUpdateRPC.Unmarshal(m, b) -} -func (m *ContactUpdateRPC) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ContactUpdateRPC.Marshal(b, m, deterministic) -} -func (m *ContactUpdateRPC) XXX_Merge(src proto.Message) { - xxx_messageInfo_ContactUpdateRPC.Merge(m, src) -} -func (m *ContactUpdateRPC) XXX_Size() int { - return xxx_messageInfo_ContactUpdateRPC.Size(m) -} -func (m *ContactUpdateRPC) XXX_DiscardUnknown() { - xxx_messageInfo_ContactUpdateRPC.DiscardUnknown(m) -} - -var xxx_messageInfo_ContactUpdateRPC proto.InternalMessageInfo - -func (m *ContactUpdateRPC) GetSrc() string { - if m != nil { - return m.Src - } - return "" -} - -func (m *ContactUpdateRPC) GetDst() string { - if m != nil { - return m.Dst - } - return "" -} - -func (m *ContactUpdateRPC) GetPayload() *ContactUpdatePayload { - if m != nil { - return m.Payload - } - return nil -} - -// Incoming messages -type ChatProtocolMessage struct { - Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ChatProtocolMessage) Reset() { *m = ChatProtocolMessage{} } -func (m *ChatProtocolMessage) String() string { return proto.CompactTextString(m) } -func (*ChatProtocolMessage) ProtoMessage() {} -func (*ChatProtocolMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_8c585a45e2093e54, []int{4} -} - -func (m *ChatProtocolMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ChatProtocolMessage.Unmarshal(m, b) -} -func (m *ChatProtocolMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ChatProtocolMessage.Marshal(b, m, deterministic) -} -func (m *ChatProtocolMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChatProtocolMessage.Merge(m, src) -} -func (m *ChatProtocolMessage) XXX_Size() int { - return xxx_messageInfo_ChatProtocolMessage.Size(m) -} -func (m *ChatProtocolMessage) XXX_DiscardUnknown() { - xxx_messageInfo_ChatProtocolMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_ChatProtocolMessage proto.InternalMessageInfo - -func (m *ChatProtocolMessage) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -func init() { - proto.RegisterType((*ChatMessagePayload)(nil), "chat.ChatMessagePayload") - proto.RegisterType((*ContactUpdatePayload)(nil), "chat.ContactUpdatePayload") - proto.RegisterType((*OneToOneRPC)(nil), "chat.OneToOneRPC") - proto.RegisterType((*ContactUpdateRPC)(nil), "chat.ContactUpdateRPC") - proto.RegisterType((*ChatProtocolMessage)(nil), "chat.ChatProtocolMessage") -} - -func init() { proto.RegisterFile("chat.proto", fileDescriptor_8c585a45e2093e54) } - -var fileDescriptor_8c585a45e2093e54 = []byte{ - // 314 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0x4a, 0xc3, 0x40, - 0x10, 0xc6, 0x59, 0x5b, 0xd4, 0x4e, 0x2a, 0x94, 0xd5, 0x43, 0xd0, 0x83, 0x35, 0x5e, 0x7a, 0xaa, - 0xa0, 0xbe, 0x41, 0x4f, 0x22, 0xd2, 0x12, 0xaa, 0xd7, 0xb0, 0x6e, 0xa6, 0x7f, 0xe8, 0x66, 0x77, - 0xc9, 0xae, 0x42, 0x5f, 0xc0, 0x37, 0xf0, 0x7d, 0x65, 0x36, 0x1b, 0x35, 0xe0, 0xc1, 0xdb, 0x37, - 0x5f, 0x86, 0xf9, 0x7e, 0x93, 0x59, 0x00, 0xb9, 0x11, 0x7e, 0x6a, 0x6b, 0xe3, 0x0d, 0xef, 0x93, - 0xce, 0x3e, 0x19, 0xf0, 0xd9, 0x46, 0xf8, 0x27, 0x74, 0x4e, 0xac, 0x71, 0x21, 0xf6, 0xca, 0x88, - 0x92, 0xa7, 0x70, 0x24, 0x8d, 0xf6, 0xa8, 0x7d, 0xca, 0xc6, 0x6c, 0x32, 0xc8, 0xdb, 0x92, 0x5f, - 0xc1, 0x30, 0xca, 0xc2, 0xef, 0x2d, 0xa6, 0x07, 0xe1, 0x73, 0x12, 0xbd, 0xe5, 0xde, 0x22, 0xb5, - 0x54, 0xcd, 0xb8, 0xa6, 0xa5, 0xd7, 0xb4, 0x44, 0x2f, 0xb4, 0x5c, 0x42, 0x22, 0x95, 0x91, 0xbb, - 0xe2, 0x5d, 0xa8, 0x37, 0x4c, 0xfb, 0x63, 0x36, 0x61, 0x39, 0x04, 0xeb, 0x85, 0x9c, 0xec, 0x83, - 0xc1, 0xd9, 0xcc, 0x68, 0x2f, 0xa4, 0x7f, 0xb6, 0xa5, 0xf0, 0xdf, 0x64, 0x1c, 0xfa, 0x5a, 0x54, - 0x18, 0xb1, 0x82, 0xe6, 0xd7, 0x70, 0x62, 0x6b, 0xb3, 0xda, 0x2a, 0x2c, 0xb6, 0x95, 0x58, 0xb7, - 0x50, 0xc3, 0x68, 0x3e, 0x90, 0x47, 0x2b, 0x89, 0xb2, 0xac, 0xd1, 0xb9, 0x08, 0xd4, 0x96, 0xfc, - 0x02, 0x06, 0x2b, 0x59, 0x15, 0xde, 0xec, 0x50, 0x07, 0x94, 0x41, 0x7e, 0xbc, 0x92, 0xd5, 0x92, - 0xea, 0xec, 0x11, 0x92, 0xb9, 0xc6, 0xa5, 0x99, 0x6b, 0xcc, 0x17, 0x33, 0x3e, 0x82, 0x9e, 0xab, - 0x65, 0x4c, 0x27, 0x49, 0x4e, 0xe9, 0x7c, 0x8c, 0x24, 0x49, 0x49, 0xb6, 0xa1, 0x0d, 0x49, 0xc3, - 0xbc, 0x2d, 0x33, 0x05, 0xa3, 0xce, 0x52, 0xff, 0x9d, 0x78, 0xdf, 0x9d, 0x98, 0xdc, 0x9e, 0x4f, - 0xc3, 0x25, 0xff, 0xfa, 0x43, 0x3f, 0x69, 0x37, 0x70, 0x4a, 0xa7, 0x5d, 0xd0, 0xb9, 0xa5, 0x51, - 0xf1, 0xc4, 0xbf, 0xf1, 0x58, 0x07, 0xef, 0xf5, 0x30, 0xbc, 0x8c, 0xbb, 0xaf, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xad, 0x31, 0x5d, 0x6c, 0x27, 0x02, 0x00, 0x00, -} diff --git a/messaging/chat/encryption.go b/messaging/chat/encryption.go index 854147b88..b5db8a746 100644 --- a/messaging/chat/encryption.go +++ b/messaging/chat/encryption.go @@ -12,9 +12,9 @@ import ( "github.com/ethereum/go-ethereum/log" dr "github.com/status-im/doubleratchet" - "github.com/status-im/status-go/messaging/chat/crypto" - "github.com/status-im/status-go/messaging/chat/multidevice" "github.com/status-im/status-go/messaging/chat/protobuf" + "github.com/status-im/status-go/messaging/crypto" + "github.com/status-im/status-go/messaging/multidevice" ) var ( @@ -38,7 +38,7 @@ type ConfirmationData struct { // EncryptionService defines a service that is responsible for the encryption aspect of the protocol. type EncryptionService struct { log log.Logger - persistence PersistenceService + persistence Persistence config EncryptionServiceConfig messageIDs map[string]*ConfirmationData mutex sync.Mutex @@ -71,7 +71,7 @@ func DefaultEncryptionServiceConfig(installationID string) EncryptionServiceConf } // NewEncryptionService creates a new EncryptionService instance. -func NewEncryptionService(p PersistenceService, config EncryptionServiceConfig) *EncryptionService { +func NewEncryptionService(p Persistence, config EncryptionServiceConfig) *EncryptionService { logger := log.New("package", "status-go/services/sshext.chat") logger.Info("Initialized encryption service", "installationID", config.InstallationID) return &EncryptionService{ diff --git a/messaging/chat/encryption_multi_device_test.go b/messaging/chat/encryption_multi_device_test.go index 2d3808ee0..34535dd35 100644 --- a/messaging/chat/encryption_multi_device_test.go +++ b/messaging/chat/encryption_multi_device_test.go @@ -8,8 +8,8 @@ import ( "os" "testing" - "github.com/status-im/status-go/messaging/chat/multidevice" - "github.com/status-im/status-go/messaging/chat/sharedsecret" + "github.com/status-im/status-go/messaging/multidevice" + "github.com/status-im/status-go/messaging/sharedsecret" ) const ( diff --git a/messaging/chat/encryption_test.go b/messaging/chat/encryption_test.go index b7e553d2c..8bd23bcd1 100644 --- a/messaging/chat/encryption_test.go +++ b/messaging/chat/encryption_test.go @@ -13,9 +13,9 @@ import ( "time" "github.com/ethereum/go-ethereum/crypto" - "github.com/status-im/status-go/messaging/chat/multidevice" "github.com/status-im/status-go/messaging/chat/protobuf" - "github.com/status-im/status-go/messaging/chat/sharedsecret" + "github.com/status-im/status-go/messaging/multidevice" + "github.com/status-im/status-go/messaging/sharedsecret" "github.com/stretchr/testify/suite" ) diff --git a/messaging/chat/persistence.go b/messaging/chat/persistence.go index 18bc61207..ee855f357 100644 --- a/messaging/chat/persistence.go +++ b/messaging/chat/persistence.go @@ -4,8 +4,8 @@ import ( "crypto/ecdsa" dr "github.com/status-im/doubleratchet" - "github.com/status-im/status-go/messaging/chat/multidevice" "github.com/status-im/status-go/messaging/chat/protobuf" + "github.com/status-im/status-go/messaging/multidevice" ) // RatchetInfo holds the current ratchet state @@ -20,8 +20,8 @@ type RatchetInfo struct { InstallationID string } -// PersistenceService defines the interface for a storage service -type PersistenceService interface { +// Persistence defines the interface for a storage service +type Persistence interface { // GetKeysStorage returns the associated double ratchet KeysStorage object. GetKeysStorage() dr.KeysStorage // GetSessionStorage returns the associated double ratchet SessionStorage object. diff --git a/messaging/chat/protocol.go b/messaging/chat/protocol.go index 3ca4299dd..bd3c83bec 100644 --- a/messaging/chat/protocol.go +++ b/messaging/chat/protocol.go @@ -3,11 +3,14 @@ package chat import ( "crypto/ecdsa" "errors" + "fmt" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" - "github.com/status-im/status-go/messaging/chat/multidevice" + "github.com/status-im/status-go/messaging/chat/protobuf" - "github.com/status-im/status-go/messaging/chat/sharedsecret" + "github.com/status-im/status-go/messaging/multidevice" + "github.com/status-im/status-go/messaging/sharedsecret" ) const ProtocolVersion = 1 @@ -197,17 +200,52 @@ func (p *ProtocolService) BuildDHMessage(myIdentityKey *ecdsa.PrivateKey, destin // ProcessPublicBundle processes a received X3DH bundle. func (p *ProtocolService) ProcessPublicBundle(myIdentityKey *ecdsa.PrivateKey, bundle *protobuf.Bundle) ([]*multidevice.Installation, error) { + p.log.Debug("Processing bundle", "bundle", bundle) + if err := p.encryption.ProcessPublicBundle(myIdentityKey, bundle); err != nil { return nil, err } - theirIdentityKey, err := ExtractIdentity(bundle) - p.log.Debug("Processing bundle", "bundle", bundle) + installations, fromOurs, err := p.recoverInstallationsFromBundle(myIdentityKey, bundle) if err != nil { return nil, err } - return p.multidevice.ProcessPublicBundle(myIdentityKey, theirIdentityKey, bundle) + // TODO(adam): why do we add installations using identity obtained from GetIdentity() + // instead of the output of crypto.CompressPubkey()? I tried the second option + // and the unit tests TestTopic and TestMaxDevices fail. + return p.multidevice.AddInstallations(bundle.GetIdentity(), bundle.GetTimestamp(), installations, fromOurs) +} + +// recoverInstallationsFromBundle extracts installations from the bundle. +// It returns extracted installations and true if the installations +// are ours, i.e. the bundle was created by our identity key. +func (p *ProtocolService) recoverInstallationsFromBundle(myIdentityKey *ecdsa.PrivateKey, bundle *protobuf.Bundle) ([]*multidevice.Installation, bool, error) { + var installations []*multidevice.Installation + + theirIdentity, err := ExtractIdentity(bundle) + if err != nil { + return nil, false, err + } + + myIdentityStr := fmt.Sprintf("0x%x", crypto.FromECDSAPub(&myIdentityKey.PublicKey)) + theirIdentityStr := fmt.Sprintf("0x%x", crypto.FromECDSAPub(theirIdentity)) + // Any device from other peers will be considered enabled, ours needs to + // be explicitly enabled + fromOurIdentity := theirIdentityStr != myIdentityStr + signedPreKeys := bundle.GetSignedPreKeys() + + for installationID, signedPreKey := range signedPreKeys { + if installationID != p.multidevice.InstallationID() { + installations = append(installations, &multidevice.Installation{ + Identity: theirIdentityStr, + ID: installationID, + Version: signedPreKey.GetProtocolVersion(), + }) + } + } + + return installations, fromOurIdentity, nil } // GetBundle retrieves or creates a X3DH bundle, given a private identity key. diff --git a/messaging/chat/protocol_test.go b/messaging/chat/protocol_test.go index 3c784bbbc..d303d5331 100644 --- a/messaging/chat/protocol_test.go +++ b/messaging/chat/protocol_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/ethereum/go-ethereum/crypto" - "github.com/status-im/status-go/messaging/chat/multidevice" - "github.com/status-im/status-go/messaging/chat/sharedsecret" + "github.com/status-im/status-go/messaging/multidevice" + "github.com/status-im/status-go/messaging/sharedsecret" "github.com/stretchr/testify/suite" ) diff --git a/messaging/chat/sql_lite_persistence.go b/messaging/chat/sql_lite_persistence.go index bb6889f80..17f33148a 100644 --- a/messaging/chat/sql_lite_persistence.go +++ b/messaging/chat/sql_lite_persistence.go @@ -6,13 +6,13 @@ import ( "strings" "github.com/ethereum/go-ethereum/crypto" - dr "github.com/status-im/doubleratchet" - ecrypto "github.com/status-im/status-go/messaging/chat/crypto" - chatDB "github.com/status-im/status-go/messaging/chat/db" - "github.com/status-im/status-go/messaging/chat/multidevice" + "github.com/status-im/status-go/messaging/chat/protobuf" - "github.com/status-im/status-go/messaging/chat/sharedsecret" + ecrypto "github.com/status-im/status-go/messaging/crypto" + msgdb "github.com/status-im/status-go/messaging/db" + "github.com/status-im/status-go/messaging/multidevice" + "github.com/status-im/status-go/messaging/sharedsecret" ) // A safe max number of rows @@ -23,7 +23,7 @@ type SQLLitePersistence struct { DB *sql.DB keysStorage dr.KeysStorage sessionStorage dr.SessionStorage - secretStorage sharedsecret.PersistenceService + secretStorage sharedsecret.Persistence multideviceStorage multidevice.Persistence } @@ -81,7 +81,7 @@ func (s *SQLLitePersistence) GetSessionStorage() dr.SessionStorage { } // GetSharedSecretStorage returns the associated secretStorageObject -func (s *SQLLitePersistence) GetSharedSecretStorage() sharedsecret.PersistenceService { +func (s *SQLLitePersistence) GetSharedSecretStorage() sharedsecret.Persistence { return s.secretStorage } @@ -92,7 +92,7 @@ func (s *SQLLitePersistence) GetMultideviceStorage() multidevice.Persistence { // Open opens a file at the specified path func (s *SQLLitePersistence) Open(path string, key string) error { - db, err := chatDB.Open(path, key, chatDB.KdfIterationsNumber) + db, err := msgdb.Open(path, key, msgdb.KdfIterationsNumber) if err != nil { return err } diff --git a/messaging/chat/sql_lite_persistence_test.go b/messaging/chat/sql_lite_persistence_test.go index cd7f87042..6f421883f 100644 --- a/messaging/chat/sql_lite_persistence_test.go +++ b/messaging/chat/sql_lite_persistence_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/crypto" - "github.com/status-im/status-go/messaging/chat/multidevice" + "github.com/status-im/status-go/messaging/multidevice" "github.com/stretchr/testify/suite" ) @@ -23,7 +23,7 @@ type SQLLitePersistenceTestSuite struct { suite.Suite // nolint: structcheck, megacheck db *sql.DB - service PersistenceService + service Persistence } func (s *SQLLitePersistenceTestSuite) SetupTest() { diff --git a/messaging/chat/crypto/crypto.go b/messaging/crypto/crypto.go similarity index 100% rename from messaging/chat/crypto/crypto.go rename to messaging/crypto/crypto.go diff --git a/messaging/chat/crypto/crypto_test.go b/messaging/crypto/crypto_test.go similarity index 100% rename from messaging/chat/crypto/crypto_test.go rename to messaging/crypto/crypto_test.go diff --git a/messaging/chat/crypto/ethereum_crypto.go b/messaging/crypto/ethereum_crypto.go similarity index 99% rename from messaging/chat/crypto/ethereum_crypto.go rename to messaging/crypto/ethereum_crypto.go index 168777c3e..bf316d829 100644 --- a/messaging/chat/crypto/ethereum_crypto.go +++ b/messaging/crypto/ethereum_crypto.go @@ -9,9 +9,8 @@ import ( "fmt" "io" - "github.com/ethereum/go-ethereum/crypto/ecies" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/ecies" dr "github.com/status-im/doubleratchet" "golang.org/x/crypto/hkdf" ) diff --git a/messaging/chat/db/db.go b/messaging/db/db.go similarity index 98% rename from messaging/chat/db/db.go rename to messaging/db/db.go index 56f1ee1c9..3e8b47033 100644 --- a/messaging/chat/db/db.go +++ b/messaging/db/db.go @@ -9,7 +9,7 @@ import ( "github.com/status-im/migrate/v4" "github.com/status-im/migrate/v4/database/sqlcipher" "github.com/status-im/migrate/v4/source/go_bindata" - "github.com/status-im/status-go/messaging/chat/db/migrations" + "github.com/status-im/status-go/messaging/db/migrations" ) const exportDB = "SELECT sqlcipher_export('newdb')" diff --git a/messaging/chat/db/migrations/bindata.go b/messaging/db/migrations/bindata.go similarity index 100% rename from messaging/chat/db/migrations/bindata.go rename to messaging/db/migrations/bindata.go diff --git a/messaging/filter/service.go b/messaging/filter/service.go index 98d12d832..4531b8d0c 100644 --- a/messaging/filter/service.go +++ b/messaging/filter/service.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" - "github.com/status-im/status-go/messaging/chat/sharedsecret" + "github.com/status-im/status-go/messaging/sharedsecret" whisper "github.com/status-im/whisper/whisperv6" "math/big" "sync" diff --git a/messaging/filter/service_test.go b/messaging/filter/service_test.go index 266208962..49b3afb38 100644 --- a/messaging/filter/service_test.go +++ b/messaging/filter/service_test.go @@ -8,10 +8,11 @@ import ( "testing" "github.com/ethereum/go-ethereum/crypto" - chatDB "github.com/status-im/status-go/messaging/chat/db" - "github.com/status-im/status-go/messaging/chat/sharedsecret" whisper "github.com/status-im/whisper/whisperv6" "github.com/stretchr/testify/suite" + + msgdb "github.com/status-im/status-go/messaging/db" + "github.com/status-im/status-go/messaging/sharedsecret" ) func TestServiceTestSuite(t *testing.T) { @@ -63,7 +64,7 @@ func (s *ServiceTestSuite) SetupTest() { s.keys = append(s.keys, testKey) } - db, err := chatDB.Open(s.path, "", 0) + db, err := msgdb.Open(s.path, "", 0) s.Require().NoError(err) // Build services diff --git a/messaging/chat/multidevice/persistence.go b/messaging/multidevice/persistence.go similarity index 100% rename from messaging/chat/multidevice/persistence.go rename to messaging/multidevice/persistence.go diff --git a/messaging/chat/multidevice/service.go b/messaging/multidevice/service.go similarity index 74% rename from messaging/chat/multidevice/service.go rename to messaging/multidevice/service.go index 38ec66e4b..05d572d00 100644 --- a/messaging/chat/multidevice/service.go +++ b/messaging/multidevice/service.go @@ -2,9 +2,8 @@ package multidevice import ( "crypto/ecdsa" - "fmt" + "github.com/ethereum/go-ethereum/crypto" - "github.com/status-im/status-go/messaging/chat/protobuf" ) type InstallationMetadata struct { @@ -49,6 +48,10 @@ type Service struct { config *Config } +func (s *Service) InstallationID() string { + return s.config.InstallationID +} + func (s *Service) GetActiveInstallations(identity *ecdsa.PublicKey) ([]*Installation, error) { identityC := crypto.CompressPubkey(identity) return s.persistence.GetActiveInstallations(s.config.MaxInstallations, identityC) @@ -96,6 +99,10 @@ func (s *Service) GetOurInstallations(identity *ecdsa.PublicKey) ([]*Installatio return installations, nil } +func (s *Service) AddInstallations(identity []byte, timestamp int64, installations []*Installation, defaultEnabled bool) ([]*Installation, error) { + return s.persistence.AddInstallations(identity, timestamp, installations, defaultEnabled) +} + func (s *Service) SetInstallationMetadata(identity *ecdsa.PublicKey, installationID string, metadata *InstallationMetadata) error { identityC := crypto.CompressPubkey(identity) return s.persistence.SetInstallationMetadata(identityC, installationID, metadata) @@ -110,28 +117,3 @@ func (s *Service) DisableInstallation(myIdentityKey *ecdsa.PublicKey, installati myIdentityKeyC := crypto.CompressPubkey(myIdentityKey) return s.persistence.DisableInstallation(myIdentityKeyC, installationID) } - -// ProcessPublicBundle persists a bundle and returns a list of tuples identity/installationID -func (s *Service) ProcessPublicBundle(myIdentityKey *ecdsa.PrivateKey, theirIdentity *ecdsa.PublicKey, b *protobuf.Bundle) ([]*Installation, error) { - signedPreKeys := b.GetSignedPreKeys() - var installations []*Installation - - myIdentityStr := fmt.Sprintf("0x%x", crypto.FromECDSAPub(&myIdentityKey.PublicKey)) - theirIdentityStr := fmt.Sprintf("0x%x", crypto.FromECDSAPub(theirIdentity)) - - // Any device from other peers will be considered enabled, ours needs to - // be explicitly enabled - fromOurIdentity := theirIdentityStr != myIdentityStr - - for installationID, signedPreKey := range signedPreKeys { - if installationID != s.config.InstallationID { - installations = append(installations, &Installation{ - Identity: theirIdentityStr, - ID: installationID, - Version: signedPreKey.GetProtocolVersion(), - }) - } - } - - return s.persistence.AddInstallations(b.GetIdentity(), b.GetTimestamp(), installations, fromOurIdentity) -} diff --git a/messaging/chat/multidevice/sql_lite_persistence.go b/messaging/multidevice/sql_lite_persistence.go similarity index 100% rename from messaging/chat/multidevice/sql_lite_persistence.go rename to messaging/multidevice/sql_lite_persistence.go diff --git a/messaging/chat/multidevice/sql_lite_persistence_test.go b/messaging/multidevice/sql_lite_persistence_test.go similarity index 98% rename from messaging/chat/multidevice/sql_lite_persistence_test.go rename to messaging/multidevice/sql_lite_persistence_test.go index 60131c129..aa6cc5f3e 100644 --- a/messaging/chat/multidevice/sql_lite_persistence_test.go +++ b/messaging/multidevice/sql_lite_persistence_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - chatDB "github.com/status-im/status-go/messaging/chat/db" + msgdb "github.com/status-im/status-go/messaging/db" "github.com/stretchr/testify/suite" ) @@ -27,7 +27,7 @@ type SQLLitePersistenceTestSuite struct { func (s *SQLLitePersistenceTestSuite) SetupTest() { os.Remove(dbPath) - db, err := chatDB.Open(dbPath, "", 0) + db, err := msgdb.Open(dbPath, "", 0) s.Require().NoError(err) s.service = NewSQLLitePersistence(db) diff --git a/messaging/publisher/publisher.go b/messaging/publisher/publisher.go index 04cd91d6c..eb2652676 100644 --- a/messaging/publisher/publisher.go +++ b/messaging/publisher/publisher.go @@ -13,9 +13,9 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/status-im/status-go/messaging/chat" - "github.com/status-im/status-go/messaging/chat/multidevice" "github.com/status-im/status-go/messaging/chat/protobuf" "github.com/status-im/status-go/messaging/filter" + "github.com/status-im/status-go/messaging/multidevice" "github.com/status-im/status-go/services/shhext/whisperutils" @@ -62,7 +62,7 @@ func New(w *whisper.Whisper, c Config) *Publisher { config: c, whisper: w, whisperAPI: whisper.NewPublicWhisperAPI(w), - log: log.New("package", "status-go/services/publisher.Publisher"), + log: log.New("package", "status-go/messaging/publisher.Publisher"), } } @@ -242,22 +242,15 @@ func (p *Publisher) ProcessMessage(msg *whisper.Message, msgID []byte) error { } // CreateDirectMessage creates a 1:1 chat message -func (p *Publisher) CreateDirectMessage(signature string, destination hexutil.Bytes, DH bool, payload []byte) (*whisper.NewMessage, error) { +func (p *Publisher) CreateDirectMessage(privateKey *ecdsa.PrivateKey, publicKey *ecdsa.PublicKey, DH bool, payload []byte) (*whisper.NewMessage, error) { if !p.config.PFSEnabled { return nil, ErrPFSNotEnabled } - privateKey, err := p.whisper.GetPrivateKey(signature) - if err != nil { - return nil, err - } - - publicKey, err := crypto.UnmarshalPubkey(destination) - if err != nil { - return nil, err - } - - var msgSpec *chat.ProtocolMessageSpec + var ( + msgSpec *chat.ProtocolMessageSpec + err error + ) if DH { p.log.Debug("Building dh message") @@ -270,7 +263,7 @@ func (p *Publisher) CreateDirectMessage(signature string, destination hexutil.By return nil, err } - whisperMessage, err := p.directMessageToWhisper(privateKey, publicKey, destination, signature, msgSpec) + whisperMessage, err := p.directMessageToWhisper(privateKey, publicKey, msgSpec) if err != nil { p.log.Error("sshext-service", "error building whisper message", err) return nil, err @@ -279,7 +272,7 @@ func (p *Publisher) CreateDirectMessage(signature string, destination hexutil.By return whisperMessage, nil } -func (p *Publisher) directMessageToWhisper(myPrivateKey *ecdsa.PrivateKey, theirPublicKey *ecdsa.PublicKey, destination hexutil.Bytes, signature string, spec *chat.ProtocolMessageSpec) (*whisper.NewMessage, error) { +func (p *Publisher) directMessageToWhisper(myPrivateKey *ecdsa.PrivateKey, theirPublicKey *ecdsa.PublicKey, spec *chat.ProtocolMessageSpec) (*whisper.NewMessage, error) { // marshal for sending to wire marshaledMessage, err := proto.Marshal(spec.Message) if err != nil { @@ -287,9 +280,18 @@ func (p *Publisher) directMessageToWhisper(myPrivateKey *ecdsa.PrivateKey, their return nil, err } + // We rely on the fact that a deterministic ID is created for the same keys. + sigID, err := p.whisper.AddKeyPair(myPrivateKey) + if err != nil { + p.log.Error("failed to add key pair in order to get signature ID", "err", err) + return nil, err + } + + destination := hexutil.Bytes(crypto.FromECDSAPub(theirPublicKey)) + whisperMessage := whisperutils.DefaultWhisperMessage() whisperMessage.Payload = marshaledMessage - whisperMessage.Sig = signature + whisperMessage.Sig = sigID if spec.SharedSecret != nil { chat := p.getNegotiatedChat(theirPublicKey) @@ -320,7 +322,7 @@ func (p *Publisher) directMessageToWhisper(myPrivateKey *ecdsa.PrivateKey, their } // CreatePublicMessage sends a public chat message to the underlying transport -func (p *Publisher) CreatePublicMessage(signature string, chatID string, payload []byte, wrap bool) (*whisper.NewMessage, error) { +func (p *Publisher) CreatePublicMessage(privateKey *ecdsa.PrivateKey, chatID string, payload []byte, wrap bool) (*whisper.NewMessage, error) { if !p.config.PFSEnabled { return nil, ErrPFSNotEnabled } @@ -329,11 +331,17 @@ func (p *Publisher) CreatePublicMessage(signature string, chatID string, payload if filter == nil { return nil, errors.New("not subscribed to chat") } - p.log.Info("SIG", signature) + + sigID, err := p.whisper.AddKeyPair(privateKey) + if err != nil { + return nil, fmt.Errorf("failed to get a signature ID: %v", err) + } + + p.log.Info("signature ID", sigID) // Enrich with transport layer info whisperMessage := whisperutils.DefaultWhisperMessage() - whisperMessage.Sig = signature + whisperMessage.Sig = sigID whisperMessage.Topic = whisperutils.ToTopic(chatID) whisperMessage.SymKeyID = filter.SymKeyID @@ -426,7 +434,7 @@ func (p *Publisher) sendContactCode() (*whisper.NewMessage, error) { identity := fmt.Sprintf("%x", crypto.FromECDSAPub(&privateKey.PublicKey)) - message, err := p.CreatePublicMessage("0x"+identity, filter.ContactCodeTopic(identity), nil, true) + message, err := p.CreatePublicMessage(privateKey, filter.ContactCodeTopic(identity), nil, true) if err != nil { p.log.Error("could not build contact code", "identity", identity, "err", err) return nil, err diff --git a/messaging/publisher/publisher_test.go b/messaging/publisher/publisher_test.go index f997f23d7..986221743 100644 --- a/messaging/publisher/publisher_test.go +++ b/messaging/publisher/publisher_test.go @@ -11,9 +11,9 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/status-im/status-go/messaging/chat" - "github.com/status-im/status-go/messaging/chat/multidevice" - "github.com/status-im/status-go/messaging/chat/sharedsecret" "github.com/status-im/status-go/messaging/filter" + "github.com/status-im/status-go/messaging/multidevice" + "github.com/status-im/status-go/messaging/sharedsecret" "github.com/status-im/status-go/services/shhext/whisperutils" whisper "github.com/status-im/whisper/whisperv6" "github.com/stretchr/testify/suite" @@ -108,7 +108,7 @@ func (s *ServiceTestSuite) SetupTest() { } func (s *ServiceTestSuite) TestCreateDirectMessage() { - newMessage, err := s.alice.CreateDirectMessage(s.aliceKey.keyID, s.bobKey.publicKeyBytes, false, []byte("hello")) + newMessage, err := s.alice.CreateDirectMessage(s.aliceKey.privateKey, &s.bobKey.privateKey.PublicKey, false, []byte("hello")) s.Require().NoError(err) message := &whisper.Message{ @@ -125,7 +125,7 @@ func (s *ServiceTestSuite) TestCreateDirectMessage() { func (s *ServiceTestSuite) TestTopic() { // We build an initial message - newMessage1, err := s.alice.CreateDirectMessage(s.aliceKey.keyID, s.bobKey.publicKeyBytes, false, []byte("hello")) + newMessage1, err := s.alice.CreateDirectMessage(s.aliceKey.privateKey, &s.bobKey.privateKey.PublicKey, false, []byte("hello")) s.Require().NoError(err) message1 := &whisper.Message{ @@ -155,7 +155,7 @@ func (s *ServiceTestSuite) TestTopic() { s.Require().EqualError(err, chat.ErrNoPayload.Error()) // We build another message, this time it should use the partitioned topic - newMessage3, err := s.alice.CreateDirectMessage(s.aliceKey.keyID, s.bobKey.publicKeyBytes, false, []byte("hello")) + newMessage3, err := s.alice.CreateDirectMessage(s.aliceKey.privateKey, &s.bobKey.privateKey.PublicKey, false, []byte("hello")) s.Require().NoError(err) message3 := &whisper.Message{ @@ -173,7 +173,7 @@ func (s *ServiceTestSuite) TestTopic() { s.Require().NoError(err) // We build another message, this time it should use the negotiated topic - newMessage4, err := s.bob.CreateDirectMessage(s.bobKey.keyID, s.aliceKey.publicKeyBytes, false, []byte("hello")) + newMessage4, err := s.bob.CreateDirectMessage(s.bobKey.privateKey, &s.aliceKey.privateKey.PublicKey, false, []byte("hello")) s.Require().NoError(err) message4 := &whisper.Message{ @@ -198,7 +198,7 @@ func (s *ServiceTestSuite) TestTopic() { s.Require().NoError(err) // Alice sends another message to Bob, this time it should use the negotiated topic - newMessage5, err := s.alice.CreateDirectMessage(s.aliceKey.keyID, s.bobKey.publicKeyBytes, false, []byte("hello")) + newMessage5, err := s.alice.CreateDirectMessage(s.aliceKey.privateKey, &s.bobKey.privateKey.PublicKey, false, []byte("hello")) s.Require().NoError(err) message5 := &whisper.Message{ diff --git a/messaging/chat/sharedsecret/persistence.go b/messaging/sharedsecret/persistence.go similarity index 98% rename from messaging/chat/sharedsecret/persistence.go rename to messaging/sharedsecret/persistence.go index 958f47b53..29a97c4cc 100644 --- a/messaging/chat/sharedsecret/persistence.go +++ b/messaging/sharedsecret/persistence.go @@ -5,7 +5,7 @@ import ( "strings" ) -type PersistenceService interface { +type Persistence interface { // Add adds a shared secret, associated with an identity and an installationID Add(identity []byte, secret []byte, installationID string) error // Get returns a shared secret associated with multiple installationIDs diff --git a/messaging/chat/sharedsecret/service.go b/messaging/sharedsecret/service.go similarity index 93% rename from messaging/chat/sharedsecret/service.go rename to messaging/sharedsecret/service.go index 370463078..bfd07354a 100644 --- a/messaging/chat/sharedsecret/service.go +++ b/messaging/sharedsecret/service.go @@ -2,6 +2,7 @@ package sharedsecret import ( "crypto/ecdsa" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/ethereum/go-ethereum/log" @@ -11,12 +12,12 @@ const sskLen = 16 type Service struct { log log.Logger - persistence PersistenceService + persistence Persistence } -func NewService(persistence PersistenceService) *Service { +func NewService(persistence Persistence) *Service { return &Service{ - log: log.New("package", "status-go/services/sshext/chat.sharedsecret"), + log: log.New("package", "status-go/messaging/sharedsecret.Service"), persistence: persistence, } } diff --git a/messaging/chat/sharedsecret/service_test.go b/messaging/sharedsecret/service_test.go similarity index 97% rename from messaging/chat/sharedsecret/service_test.go rename to messaging/sharedsecret/service_test.go index 3930d009c..7693260c2 100644 --- a/messaging/chat/sharedsecret/service_test.go +++ b/messaging/sharedsecret/service_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/crypto" - chatDB "github.com/status-im/status-go/messaging/chat/db" + msgdb "github.com/status-im/status-go/messaging/db" "github.com/stretchr/testify/suite" ) @@ -25,7 +25,7 @@ func (s *ServiceTestSuite) SetupTest() { s.Require().NoError(err) s.path = dbFile.Name() - db, err := chatDB.Open(s.path, "", 0) + db, err := msgdb.Open(s.path, "", 0) s.Require().NoError(err) diff --git a/services/shhext/api.go b/services/shhext/api.go index 7ae09fff8..f9fc060d5 100644 --- a/services/shhext/api.go +++ b/services/shhext/api.go @@ -19,8 +19,8 @@ import ( "github.com/status-im/status-go/db" "github.com/status-im/status-go/mailserver" "github.com/status-im/status-go/messaging/chat" - "github.com/status-im/status-go/messaging/chat/multidevice" "github.com/status-im/status-go/messaging/filter" + "github.com/status-im/status-go/messaging/multidevice" "github.com/status-im/status-go/services/shhext/dedup" "github.com/status-im/status-go/services/shhext/mailservers" whisper "github.com/status-im/whisper/whisperv6" @@ -477,8 +477,13 @@ func (api *PublicAPI) ConfirmMessagesProcessedByID(messageIDs [][]byte) error { } // SendPublicMessage sends a public chat message to the underlying transport -func (api *PublicAPI) SendPublicMessage(ctx context.Context, msg chat.SendPublicMessageRPC) (hexutil.Bytes, error) { - message, err := api.service.CreatePublicMessage(msg.Sig, msg.Chat, msg.Payload, false) +func (api *PublicAPI) SendPublicMessage(ctx context.Context, msg SendPublicMessageRPC) (hexutil.Bytes, error) { + privateKey, err := api.service.w.GetPrivateKey(msg.Sig) + if err != nil { + return nil, fmt.Errorf("failed to obtain a private key from Sig: %v", err) + } + + message, err := api.service.CreatePublicMessage(privateKey, msg.Chat, msg.Payload, false) if err != nil { return nil, err } @@ -487,8 +492,18 @@ func (api *PublicAPI) SendPublicMessage(ctx context.Context, msg chat.SendPublic } // SendDirectMessage sends a 1:1 chat message to the underlying transport -func (api *PublicAPI) SendDirectMessage(ctx context.Context, msg chat.SendDirectMessageRPC) (hexutil.Bytes, error) { - message, err := api.service.CreateDirectMessage(msg.Sig, msg.PubKey, msg.DH, msg.Payload) +func (api *PublicAPI) SendDirectMessage(ctx context.Context, msg SendDirectMessageRPC) (hexutil.Bytes, error) { + privateKey, err := api.service.w.GetPrivateKey(msg.Sig) + if err != nil { + return nil, err + } + + publicKey, err := crypto.UnmarshalPubkey(msg.PubKey) + if err != nil { + return nil, err + } + + message, err := api.service.CreateDirectMessage(privateKey, publicKey, msg.DH, msg.Payload) if err != nil { return nil, err } diff --git a/messaging/chat/rpc.go b/services/shhext/rpc.go similarity index 97% rename from messaging/chat/rpc.go rename to services/shhext/rpc.go index 6e622e318..152559368 100644 --- a/messaging/chat/rpc.go +++ b/services/shhext/rpc.go @@ -1,7 +1,7 @@ // TODO: These types should be defined using protobuf, but protoc can only emit []byte instead of hexutil.Bytes, // which causes issues when marshalong to JSON on the react side. Let's do that once the chat protocol is moved to the go repo. -package chat +package shhext import ( "github.com/ethereum/go-ethereum/common/hexutil" diff --git a/services/shhext/service.go b/services/shhext/service.go index 77fac3ac7..184494952 100644 --- a/services/shhext/service.go +++ b/services/shhext/service.go @@ -17,11 +17,11 @@ import ( "github.com/status-im/status-go/db" "github.com/status-im/status-go/messaging/chat" - chatDB "github.com/status-im/status-go/messaging/chat/db" - "github.com/status-im/status-go/messaging/chat/multidevice" - "github.com/status-im/status-go/messaging/chat/sharedsecret" + msgdb "github.com/status-im/status-go/messaging/db" "github.com/status-im/status-go/messaging/filter" + "github.com/status-im/status-go/messaging/multidevice" "github.com/status-im/status-go/messaging/publisher" + "github.com/status-im/status-go/messaging/sharedsecret" "github.com/status-im/status-go/params" "github.com/status-im/status-go/services/shhext/dedup" "github.com/status-im/status-go/services/shhext/mailservers" @@ -133,11 +133,11 @@ func (s *Service) initProtocol(address, encKey, password string) error { v4Path := filepath.Join(dataDir, fmt.Sprintf("%s.v4.db", s.config.InstallationID)) if password != "" { - if err := chatDB.MigrateDBFile(v0Path, v1Path, "ON", password); err != nil { + if err := msgdb.MigrateDBFile(v0Path, v1Path, "ON", password); err != nil { return err } - if err := chatDB.MigrateDBFile(v1Path, v2Path, password, encKey); err != nil { + if err := msgdb.MigrateDBFile(v1Path, v2Path, password, encKey); err != nil { // Remove db file as created with a blank password and never used, // and there's no need to rekey in this case os.Remove(v1Path) @@ -145,13 +145,13 @@ func (s *Service) initProtocol(address, encKey, password string) error { } } - if err := chatDB.MigrateDBKeyKdfIterations(v2Path, v3Path, encKey); err != nil { + if err := msgdb.MigrateDBKeyKdfIterations(v2Path, v3Path, encKey); err != nil { os.Remove(v2Path) os.Remove(v3Path) } // Fix IOS not encrypting database - if err := chatDB.EncryptDatabase(v3Path, v4Path, encKey); err != nil { + if err := msgdb.EncryptDatabase(v3Path, v4Path, encKey); err != nil { os.Remove(v3Path) os.Remove(v4Path) } diff --git a/static/chat_db_migrations/static.go b/static/chat_db_migrations/static.go index 52b529637..00f164b9a 100644 --- a/static/chat_db_migrations/static.go +++ b/static/chat_db_migrations/static.go @@ -1,4 +1,4 @@ // Package static embeds static (JS, HTML) resources right into the binaries package static -//go:generate go-bindata -pkg migrations -o ../../messaging/chat/db/migrations/bindata.go . +//go:generate go-bindata -pkg migrations -o ../../messaging/db/migrations/bindata.go .