Documentation ¶
Index ¶
- Constants
- func CalculateContentHash(author string, messageBody string) string
- func EncryptMessageToGroup(message string, author primitives.Identity, group *Group, prevSig string) ([]byte, []byte, *groups.DecryptedGroupMessage, error)
- func GenerateRandomID() string
- func ValidateInvite(invite string) (*groups.GroupInvite, error)
- type AccessControl
- type AccessControlList
- type Attributes
- type Authorization
- type Conversation
- func (ci *Conversation) GetAttribute(scope attr.Scope, zone attr.Zone, key string) (string, bool)
- func (ci *Conversation) GetPeerAC() AccessControl
- func (ci *Conversation) HasChannel(requestedChannel int) bool
- func (ci *Conversation) IsCwtchPeer() bool
- func (ci *Conversation) IsGroup() bool
- func (ci *Conversation) IsServer() bool
- func (ci *Conversation) ServerSyncProgress() float64
- type ConversationMessage
- type Error
- type Experiments
- type Group
- func (g *Group) AttemptDecryption(ciphertext []byte, signature []byte) (bool, *groups.DecryptedGroupMessage)
- func (g *Group) CheckGroup() bool
- func (g *Group) DecryptMessage(ciphertext []byte) (bool, *groups.DecryptedGroupMessage)
- func (g *Group) EncryptMessage(message *groups.DecryptedGroupMessage) ([]byte, error)
- func (g *Group) Invite() (string, error)
- func (g *Group) VerifyGroupMessage(onion string, groupID string, message string, signature []byte) bool
- type Key
- type KeyBundle
- type KeyType
- type LocallyIndexedMessage
- type Message
- type MessageWrapper
- type Profile
- type PublicProfile
- type Timeline
- func (t *Timeline) GetCopy() *Timeline
- func (t *Timeline) GetMessages() []Message
- func (t *Timeline) GetMessagesByHash(contentHash string) ([]LocallyIndexedMessage, error)
- func (t *Timeline) Insert(mi *Message) int
- func (t *Timeline) Len() int
- func (t *Timeline) Less(i, j int) bool
- func (t *Timeline) SetMessages(messages []Message)
- func (t *Timeline) SetSendError(sig []byte, e string) bool
- func (t *Timeline) Sort()
- func (t *Timeline) Swap(i, j int)
Constants ¶
const ( InvalidEd25519PublicKey = Error("InvalidEd25519PublicKey") InconsistentKeyBundleError = Error("InconsistentKeyBundleError") )
Error definitions
const ( // BundleType - the attribute under which the signed server bundle is stored... BundleType = KeyType("server_key_bundle") // KeyTypeServerOnion - a cwtch address KeyTypeServerOnion = KeyType("bulletin_board_onion") // bulletin board // KeyTypeTokenOnion - a cwtch peer with a PoW based token protocol KeyTypeTokenOnion = KeyType("token_service_onion") //KeyTypePrivacyPass - a privacy pass based token server KeyTypePrivacyPass = KeyType("privacy_pass_public_key") )
const CurrentGroupVersion = 4
CurrentGroupVersion is used to set the version of newly created groups and make sure group structs stored are correct and up to date
const GroupInvitePrefix = "torv3"
GroupInvitePrefix identifies a particular string as being a serialized group invite.
const MaxGroupMessageLength = 1800
MaxGroupMessageLength is the maximum length of a message posted to a server group. TODO: Should this be per server?
const MessageBaseSize float64 = 463
MessageBaseSize 2021.06 byte size of an *empty* message json serialized
const OverlayChat = 1
OverlayChat is the canonical identifier for chat overlays
const OverlayFileSharing = 200
OverlayFileSharing is the canonical identifier for the file sharing overlay
const OverlayInviteContact = 100
OverlayInviteContact is the canonical identifier for the contact invite overlay
const OverlayInviteGroup = 101
OverlayInviteGroup is the canonical identifier for the group invite overlay
const OverlayManageGroupEvent = 0x402
ManageGroupEvent is the canonical identifier for the manage group overlay
Variables ¶
This section is empty.
Functions ¶
func CalculateContentHash ¶ added in v0.14.0
CalculateContentHash derives a hash using the author and the message body. It is intended to be globally referencable in the context of a single conversation
func EncryptMessageToGroup ¶ added in v0.14.0
func EncryptMessageToGroup(message string, author primitives.Identity, group *Group, prevSig string) ([]byte, []byte, *groups.DecryptedGroupMessage, error)
EncryptMessageToGroup when given a message and a group, encrypts and signs the message under the group and profile
func GenerateRandomID ¶ added in v0.3.7
func GenerateRandomID() string
GenerateRandomID generates a random 16 byte hex id code
func ValidateInvite ¶ added in v0.8.0
func ValidateInvite(invite string) (*groups.GroupInvite, error)
ValidateInvite takes in a serialized invite and returns the invite structure if it is cryptographically valid and an error if it is not
Types ¶
type AccessControl ¶ added in v0.14.0
type AccessControl struct { Blocked bool // Any attempts from this handle to connect are blocked overrides all other settings // Basic Conversation Rights Read bool // Allows a handle to access the conversation Append bool // Allows a handle to append new messages to the conversation AutoConnect bool // Profile should automatically try to connect with peer ExchangeAttributes bool // Profile should automatically exchange attributes like Name, Profile Image, etc. // Extension Related Permissions RenderImages bool // Indicates that certain filetypes should be autodownloaded and rendered when shared by this contact ManageGroup bool // Allows this conversation to be managed by hybrid groups }
AccessControl is a type determining client assigned authorization to a peer for a given conversation
func DefaultP2PAccessControl ¶ added in v0.14.0
func DefaultP2PAccessControl() AccessControl
DefaultP2PAccessControl defaults to a semi-trusted peer with no access to special extensions.
func NoAccessControl ¶ added in v0.28.1
func NoAccessControl() AccessControl
NoAccessControl defaults to a none-trusted peer with no access to special extensions. This is used as a fall back (if due to a software glitch a contact was setup without an access control, or for special contacts that should never be involvedt in external networking e.g. notes-to-self, or managed peers)
type AccessControlList ¶ added in v0.14.0
type AccessControlList map[string]AccessControl
AccessControlList represents an access control list for a conversation. Mapping handles to conversation functions
func DeserializeAccessControlList ¶ added in v0.14.0
func DeserializeAccessControlList(data []byte) (AccessControlList, error)
DeserializeAccessControlList takes in JSON and returns an AccessControlList
func (*AccessControlList) Serialize ¶ added in v0.14.0
func (acl *AccessControlList) Serialize() []byte
Serialize transforms the ACL into json.
type Attributes ¶ added in v0.14.0
Attributes a type-driven encapsulation of an Attribute map.
func DeserializeAttributes ¶ added in v0.14.0
func DeserializeAttributes(data []byte) Attributes
DeserializeAttributes converts a JSON struct into an Attributes map
func (*Attributes) Serialize ¶ added in v0.14.0
func (a *Attributes) Serialize() []byte
Serialize transforms an Attributes map into a JSON struct
type Authorization ¶ added in v0.3.14
type Authorization string
Authorization is a type determining client assigned authorization to a peer Deprecated - Only used for Importing legacy profile formats Still used in some APIs in UI but will be replaced prior to full deprecation
const ( // AuthUnknown is an initial state for a new unseen peer AuthUnknown Authorization = "unknown" // AuthApproved means the client has approved the peer, it can send messages to us, perform GetVals, etc AuthApproved Authorization = "approved" // AuthBlocked means the client has blocked the peer, it's messages and connections should be rejected AuthBlocked Authorization = "blocked" )
type Conversation ¶ added in v0.14.0
type Conversation struct { ID int Handle string Attributes Attributes ACL AccessControlList // Deprecated, please use ACL for permissions related functions Accepted bool }
Conversation encapsulates high-level information about a conversation, including the handle, any set attributes, the access control list associated with the message tree and the accepted status of the conversation (whether the user has consented into the conversation).
func (*Conversation) GetAttribute ¶ added in v0.14.0
GetAttribute is a helper function that fetches a conversation attribute by scope, zone and key
func (*Conversation) GetPeerAC ¶ added in v0.26.0
func (ci *Conversation) GetPeerAC() AccessControl
GetPeerAC returns a suitable Access Control object for a the given peer conversation If this is called for a group conversation, this method will error and return a safe default AC.
func (*Conversation) HasChannel ¶ added in v0.28.0
func (ci *Conversation) HasChannel(requestedChannel int) bool
HasChannel returns true if the requested channel has been setup for this conversation
func (*Conversation) IsCwtchPeer ¶ added in v0.28.0
func (ci *Conversation) IsCwtchPeer() bool
IsCwtchPeer is a helper attribute that identifies whether a conversation is a cwtch peer
func (*Conversation) IsGroup ¶ added in v0.14.0
func (ci *Conversation) IsGroup() bool
IsGroup is a helper attribute that identifies whether a conversation is a legacy group
func (*Conversation) IsServer ¶ added in v0.14.0
func (ci *Conversation) IsServer() bool
IsServer is a helper attribute that identifies whether a conversation is with a server
func (*Conversation) ServerSyncProgress ¶ added in v0.15.2
func (ci *Conversation) ServerSyncProgress() float64
ServerSyncProgress is only valid during a server being in the AUTHENTICATED state and therefor in the syncing process it returns a double (0-1) representing the estimated progress of the syncing
type ConversationMessage ¶ added in v0.14.0
type ConversationMessage struct { ID int Body string Attr Attributes Signature string ContentHash string }
ConversationMessage bundles an instance of a conversation message row
type Error ¶ added in v0.4.1
type Error string
Error models some common errors that need to be handled by applications that use Cwtch
type Experiments ¶ added in v0.19.0
type Experiments struct {
// contains filtered or unexported fields
}
Experiments are optional functionality that can be enabled/disabled by an application either completely or individually. examples of experiments include File Sharing, Profile Images and Groups.
func InitExperiments ¶ added in v0.19.0
func InitExperiments(enabled bool, experiments map[string]bool) Experiments
InitExperiments encapsulates a set of experiments separate from their storage in GlobalSettings.
func (*Experiments) IsEnabled ¶ added in v0.19.0
func (e *Experiments) IsEnabled(experiment string) bool
IsEnabled is a convenience function that takes in an experiment and returns true if it is enabled. Experiments are only enabled if both global experiments are turned on and if the specific experiment is also turned on. The one exception to this is experiments that have been promoted to default functionality which may be turned on even if experiments turned off globally. These experiments are defined by DefaultEnabledFunctionality.
type Group ¶
type Group struct { // GroupID is now derived from the GroupKey and the GroupServer GroupID string GroupName string GroupKey [32]byte GroupServer string Attributes map[string]string //legacy to not use Version int Timeline Timeline `json:"-"` LocalID string }
Group defines and encapsulates Cwtch's conception of group chat. Which are sessions tied to a server under a given group key. Each group has a set of Messages.
func (*Group) AttemptDecryption ¶ added in v0.14.0
func (g *Group) AttemptDecryption(ciphertext []byte, signature []byte) (bool, *groups.DecryptedGroupMessage)
AttemptDecryption takes a ciphertext and signature and attempts to decrypt it under known groups. If successful, adds the message to the group's timeline
func (*Group) CheckGroup ¶ added in v0.8.0
CheckGroup returns true only if the ID of the group is cryptographically valid.
func (*Group) DecryptMessage ¶
func (g *Group) DecryptMessage(ciphertext []byte) (bool, *groups.DecryptedGroupMessage)
DecryptMessage takes a ciphertext and returns true and the decrypted message if the cipher text can be successfully decrypted,else false.
func (*Group) EncryptMessage ¶
func (g *Group) EncryptMessage(message *groups.DecryptedGroupMessage) ([]byte, error)
EncryptMessage takes a message and encrypts the message under the group key.
func (*Group) VerifyGroupMessage ¶ added in v0.14.0
func (g *Group) VerifyGroupMessage(onion string, groupID string, message string, signature []byte) bool
VerifyGroupMessage confirms the authenticity of a message given an sender onion, message and signature. The goal of this function is 2-fold:
- We confirm that the sender referenced in the group text is the actual sender of the message (or at least knows the senders private key)
- Secondly, we confirm that the sender sent the message to a particular group id on a specific server (it doesn't matter if we actually received this message from the server or from a hybrid protocol, all that matters is that the sender and receivers agree that this message was intended for the group
The 2nd point is important as it prevents an attack documented in the original Cwtch paper (and later at https://docs.openprivacy.ca/cwtch-security-handbook/groups.html) in which a malicious profile sets up 2 groups on two different servers with the same key and then forwards messages between them to convince the parties in each group that they are actually in one big group (with the intent to later censor and/or selectively send messages to each group).
type Key ¶ added in v0.4.0
type Key string
Key provides a wrapper for a generic public key identifier (could be an onion address, a zcash address etc.)
type KeyBundle ¶ added in v0.4.0
KeyBundle manages a collection of related keys for various different services.
func DeserializeAndVerify ¶ added in v0.4.1
DeserializeAndVerify takes in a json formatted bundle and only returns a valid key bundle if it has been signed by the server.
func NewKeyBundle ¶ added in v0.4.1
func NewKeyBundle() *KeyBundle
NewKeyBundle creates a new KeyBundle initialized with no keys.
func (*KeyBundle) AttributeBundle ¶ added in v0.4.0
AttributeBundle returns a map that can be used as part of a peer attribute bundle
func (*KeyBundle) HasKeyType ¶ added in v0.4.0
HasKeyType returns true if the bundle has a public key of a given type.
func (*KeyBundle) Sign ¶ added in v0.4.1
func (kb *KeyBundle) Sign(identity primitives.Identity)
Sign allows a server to authenticate a key bundle by signing it (this uses the tapir identity interface)
type KeyType ¶ added in v0.4.0
type KeyType string
KeyType provides a wrapper for a generic public key type identifier (could be an onion address, a zcash address etc.)
type LocallyIndexedMessage ¶ added in v0.9.1
LocallyIndexedMessage is a type wrapper around a Message and a TimeLine Index that is local to this instance of the timeline.
type Message ¶
type Message struct { Timestamp time.Time Received time.Time PeerID string Message string Signature []byte PreviousMessageSig []byte ReceivedByServer bool // messages sent to a server Acknowledged bool // peer to peer Error string `json:",omitempty"` // Application specific flags, useful for storing small amounts of metadata Flags uint64 }
Message is a local representation of a given message sent over a group chat channel.
type MessageWrapper ¶ added in v0.11.0
type MessageWrapper struct { Overlay int `json:"o"` Data string `json:"d"` // when the data was assembled SendTime *time.Time `json:"s,omitempty"` // when the data was transmitted (by protocol engine e.g. over Tor) TransitTime *time.Time `json:"t,omitempty"` // when the data was received RecvTime *time.Time `json:"r,omitempty"` }
MessageWrapper is the canonical Cwtch overlay wrapper
func DeserializeMessage ¶ added in v0.27.0
func DeserializeMessage(message string) (*MessageWrapper, error)
func (MessageWrapper) Channel ¶ added in v0.27.0
func (mw MessageWrapper) Channel() int
Channel is defined as being the last 3 bits of the overlay id Channel 0 is reserved for the main conversation Channel 2 is reserved for conversation admin (managed groups) Channel 7 is reserved for streams (no ack, no store)
func (MessageWrapper) IsStream ¶ added in v0.27.0
func (mw MessageWrapper) IsStream() bool
If Overlay is a Stream Message it should not be ackd, or stored.
type Profile ¶
type Profile struct { PublicProfile Contacts map[string]*PublicProfile Ed25519PrivateKey ed25519.PrivateKey Groups map[string]*Group }
Profile encapsulates all the attributes necessary to be a Cwtch Peer. Deprecated - Only used for Importing legacy profile formats
type PublicProfile ¶
type PublicProfile struct { Name string Ed25519PublicKey ed25519.PublicKey Authorization Authorization DeprecatedBlocked bool `json:"Blocked"` Onion string Attributes map[string]string Timeline Timeline `json:"-"` LocalID string // used by storage engine State string `json:"-"` UnacknowledgedMessages map[string]int // contains filtered or unexported fields }
PublicProfile is a local copy of a CwtchIdentity Deprecated - Only used for Importing legacy profile formats
type Timeline ¶
type Timeline struct { Messages []Message SignedGroupID []byte // contains filtered or unexported fields }
Timeline encapsulates a collection of ordered Messages, and a mechanism to access them in a threadsafe manner.
func (*Timeline) GetMessages ¶
GetMessages returns a copy of the entire timeline
func (*Timeline) GetMessagesByHash ¶ added in v0.9.1
func (t *Timeline) GetMessagesByHash(contentHash string) ([]LocallyIndexedMessage, error)
GetMessagesByHash attempts to find messages that match the given content hash in the timeline. If successful it returns a list of messages as well as their local index , on failure it returns an error. We return a list of messages because content hashes are not guaranteed to be unique from a given Peer. This allows us to do things like: ensure that reply-to and quotes reference the last seen message from the message they are quoted in or detect duplicate messages from a peer.
func (*Timeline) Less ¶
Less checks 2 Messages (i and j) in the timeline and returns true if i occurred before j, else false
func (*Timeline) SetMessages ¶
SetMessages sets the Messages of this timeline. Only to be used in loading/initialization
func (*Timeline) SetSendError ¶ added in v0.13.0
SetSendError marks a message has having some kind of application specific error. Note: The message here is indexed by signature.