otr3: github.com/twstrike/otr3 Index | Files | Directories

package otr3

import "github.com/twstrike/otr3"

Package otr3 implements the Off The Record protocol as specified in:

https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html

Introduction

Off-the-Record (OTR) Messaging allows you to have private conversations over instant messaging by providing:

Encryption
Authentication
Deniability
Perfect forward secrecy

Getting Started

OTR library provides a Conversation API for Receiving and Sending messages

import "otr3"

c := &otr3.Conversation{}

// You will need to prepare a long-term PrivateKey for otr conversation handshakes.
var priv *otr3.DSAPrivateKey
priv.Generate(rand.Reader)
c.SetOurKeys([]otr3.PrivateKey{priv})

// set the Policies.
c.Policies.RequireEncryption()
c.Policies.AllowV2()
c.Policies.AllowV3()
c.Policies.SendWhitespaceTag()
c.Policies.WhitespaceStartAKE()

// You can also setup a debug mode
c.SetDebug(true)

// Use Send and Receive for messages exchange
toSend, err := c.Send(otr3.ValidMessage("hello"))
plain, toSend, err := c.Receive(toSend[0])

// Use Authenticate to start a SMP process
toSend, err := c.StartAuthenticate("My pet's name?",[]byte{"Gopher"})
toSend, err := c.ProvideAuthenticationSecret([]byte{"Gopher"})

Index

Package Files

ake.go auth_state_machine.go authenticate.go b64.go bn_utils.go bytes.go conversation.go data.go data_message.go debug.go dh.go disconnect.go doc.go error_codes.go errors.go extra_key.go fragmentation.go hash.go heartbeat.go inject_message.go key_management.go keys.go message_events.go message_type.go messages.go otrv2.go otrv3.go padding.go policy.go query.go random.go receive.go resend.go security_events.go send.go smp.go smp_events.go smp_msg1.go smp_msg2.go smp_msg3.go smp_msg4.go smp_msg_abort.go smp_state_machine.go ssid.go tlv.go version.go whitespace.go wipe.go

func Bytes Uses

func Bytes(m []ValidMessage) [][]byte

Bytes will turn a slice of valid messages into a slice of byte slices

func ExportKeysToFile Uses

func ExportKeysToFile(acs []*Account, fname string) error

ExportKeysToFile will create the named file (or truncate it) and write all the accounts to that file in libotr format.

type Account Uses

type Account struct {
    Name     string
    Protocol string
    Key      PrivateKey
}

Account is a holder for the private key associated with an account It contains name, protocol and otr private key of an otr Account

func ImportKeys Uses

func ImportKeys(r io.Reader) ([]*Account, error)

ImportKeys will read the libotr formatted data given and return all accounts defined in it

func ImportKeysFromFile Uses

func ImportKeysFromFile(fname string) ([]*Account, error)

ImportKeysFromFile will read the libotr formatted file given and return all accounts defined in it

type Conversation Uses

type Conversation struct {
    Rand io.Reader

    Policies policies
    // contains filtered or unexported fields
}

Conversation contains all the information for a specific connection between two peers in an IM system. Policies are not supposed to change once a conversation has been used

func NewConversationWithVersion Uses

func NewConversationWithVersion(v int) *Conversation

NewConversationWithVersion creates a new conversation with the given version

func (*Conversation) AbortAuthentication Uses

func (c *Conversation) AbortAuthentication() ([]ValidMessage, error)

AbortAuthentication should be called when the user wants to abort authentication with a peer. It will return an SMP abort message to send.

func (*Conversation) End Uses

func (c *Conversation) End() (toSend []ValidMessage, err error)

End ends a secure conversation by generating a termination message for the peer and switches to unencrypted communication.

func (*Conversation) GetOurCurrentKey Uses

func (c *Conversation) GetOurCurrentKey() PrivateKey

GetOurCurrentKey returns the currently chosen key for us

func (*Conversation) GetOurKeys Uses

func (c *Conversation) GetOurKeys() []PrivateKey

GetOurKeys returns all our keys for the current conversation

func (*Conversation) GetSSID Uses

func (c *Conversation) GetSSID() [8]byte

GetSSID returns the SSID of this Conversation

func (*Conversation) GetTheirKey Uses

func (c *Conversation) GetTheirKey() PublicKey

GetTheirKey returns the public key of the other peer in this conversation

func (*Conversation) InitializeInstanceTag Uses

func (c *Conversation) InitializeInstanceTag(tag uint32) uint32

InitializeInstanceTag sets our instance tag for this conversation. If the argument is zero we will create a new instance tag and return it The instance tag created or set will be returned

func (*Conversation) IsEncrypted Uses

func (c *Conversation) IsEncrypted() bool

IsEncrypted returns true if the current conversation is private

func (*Conversation) ProvideAuthenticationSecret Uses

func (c *Conversation) ProvideAuthenticationSecret(mutualSecret []byte) ([]ValidMessage, error)

ProvideAuthenticationSecret should be called when the peer has started an authentication request, and the UI has been notified that a secret is needed It is only valid to call this function if the current SMP state is waiting for a secret to be provided. The return is the potential messages to send.

func (*Conversation) QueryMessage Uses

func (c *Conversation) QueryMessage() ValidMessage

QueryMessage will return a QueryMessage determined by Conversation Policies

func (*Conversation) Receive Uses

func (c *Conversation) Receive(m ValidMessage) (plain MessagePlaintext, toSend []ValidMessage, err error)

Receive handles a message from a peer. It returns a human readable message and zero or more messages to send back to the peer.

func (*Conversation) SMPQuestion Uses

func (c *Conversation) SMPQuestion() (string, bool)

SMPQuestion returns the current SMP question and ok if there is one, and not ok if there isn't one.

func (*Conversation) SecureSessionID Uses

func (c *Conversation) SecureSessionID() (parts []string, highlightIndex int)

SecureSessionID returns the secure session ID as two formatted strings The index returned points to the string that should be highlighted

func (*Conversation) Send Uses

func (c *Conversation) Send(m ValidMessage, trace ...interface{}) ([]ValidMessage, error)

Send takes a human readable message from the local user, possibly encrypts it and returns zero or more messages to send to the peer.

func (*Conversation) SetDebug Uses

func (c *Conversation) SetDebug(d bool)

SetDebug sets the debug mode for this conversation. If debug mode is enabled, calls to Send with a message equals to "?OTR!" will dump debug information about the current conversation state to stderr

func (*Conversation) SetErrorMessageHandler Uses

func (c *Conversation) SetErrorMessageHandler(handler ErrorMessageHandler)

SetErrorMessageHandler assigns handler for ErrorMessage

func (*Conversation) SetFragmentSize Uses

func (c *Conversation) SetFragmentSize(size uint16)

SetFragmentSize sets the maximum size for a message fragment. If specified, all messages produced by Receive and Send will be fragmented into messages of, at most, this number of bytes.

func (*Conversation) SetFriendlyQueryMessage Uses

func (c *Conversation) SetFriendlyQueryMessage(msg string)

SetFriendlyQueryMessage will set a new message as query message

func (*Conversation) SetMessageEventHandler Uses

func (c *Conversation) SetMessageEventHandler(handler MessageEventHandler)

SetMessageEventHandler assigns handler for MessageEvent

func (*Conversation) SetOurKeys Uses

func (c *Conversation) SetOurKeys(ourKeys []PrivateKey)

SetOurKeys assigns our private keys to the conversation

func (*Conversation) SetSMPEventHandler Uses

func (c *Conversation) SetSMPEventHandler(handler SMPEventHandler)

SetSMPEventHandler assigns handler for SMPEvent

func (*Conversation) SetSecurityEventHandler Uses

func (c *Conversation) SetSecurityEventHandler(handler SecurityEventHandler)

SetSecurityEventHandler assigns handler for SecurityEvent

func (*Conversation) StartAuthenticate Uses

func (c *Conversation) StartAuthenticate(question string, mutualSecret []byte) ([]ValidMessage, error)

StartAuthenticate should be called when the user wants to initiate authentication with a peer. The authentication uses an optional question message and a shared secret. The authentication will proceed until the event handler reports that SMP is complete, that a secret is needed or that SMP has failed.

func (*Conversation) UseExtraSymmetricKey Uses

func (c *Conversation) UseExtraSymmetricKey(usage uint32, usageData []byte) ([]byte, []ValidMessage, error)

UseExtraSymmetricKey takes a usage parameter and optional usageData and returns the current symmetric key and a set of messages to send in order to ask the peer to use the same symmetric key for the usage defined

type DSAPrivateKey Uses

type DSAPrivateKey struct {
    DSAPublicKey
    dsa.PrivateKey
}

DSAPrivateKey is a DSA private key

func (*DSAPrivateKey) Generate Uses

func (priv *DSAPrivateKey) Generate(rand io.Reader) error

Generate will generate a new DSA Private Key with the randomness provided. The parameter size used is 1024 and 160.

func (*DSAPrivateKey) Import Uses

func (priv *DSAPrivateKey) Import(in []byte) bool

Import parses the contents of a libotr private key file.

func (*DSAPrivateKey) Parse Uses

func (priv *DSAPrivateKey) Parse(in []byte) (index []byte, ok bool)

Parse will parse a Private Key from the given data, by first parsing the public key components and then the private key component. It returns not ok for the same reasons as PublicKey.Parse.

func (*DSAPrivateKey) PublicKey Uses

func (priv *DSAPrivateKey) PublicKey() PublicKey

PublicKey returns the public key corresponding to this private key

func (*DSAPrivateKey) Serialize Uses

func (priv *DSAPrivateKey) Serialize() []byte

Serialize will return the serialization of the private key to a byte array

func (*DSAPrivateKey) Sign Uses

func (priv *DSAPrivateKey) Sign(rand io.Reader, hashed []byte) ([]byte, error)

Sign will generate a signature of a hashed data using dsa Sign.

type DSAPublicKey Uses

type DSAPublicKey struct {
    dsa.PublicKey
}

DSAPublicKey is a DSA public key

func (*DSAPublicKey) Fingerprint Uses

func (pub *DSAPublicKey) Fingerprint() []byte

Fingerprint will generate a fingerprint of the serialized version of the key using the provided hash.

func (*DSAPublicKey) IsAvailableForVersion Uses

func (pub *DSAPublicKey) IsAvailableForVersion(v uint16) bool

IsAvailableForVersion returns true if this key is possible to use with the given version

func (*DSAPublicKey) IsSame Uses

func (pub *DSAPublicKey) IsSame(other PublicKey) bool

IsSame returns true if the given public key is a DSA public key that is equal to this key

func (*DSAPublicKey) Parse Uses

func (pub *DSAPublicKey) Parse(in []byte) (index []byte, ok bool)

Parse takes the given data and tries to parse it into the PublicKey receiver. It will return not ok if the data is malformed or not for a DSA key

func (*DSAPublicKey) Verify Uses

func (pub *DSAPublicKey) Verify(hashed, sig []byte) (nextPoint []byte, sigOk bool)

Verify will verify a signature of a hashed data using dsa Verify.

type DebugErrorMessageHandler Uses

type DebugErrorMessageHandler struct{}

DebugErrorMessageHandler is an ErrorMessageHandler that dumps all error message requests to standard error. It returns nil

func (DebugErrorMessageHandler) HandleErrorMessage Uses

func (DebugErrorMessageHandler) HandleErrorMessage(error ErrorCode) []byte

HandleErrorMessage dumps all error messages and returns nil

type DebugMessageEventHandler Uses

type DebugMessageEventHandler struct{}

DebugMessageEventHandler is a MessageEventHandler that dumps all MessageEvents to standard error

func (DebugMessageEventHandler) HandleMessageEvent Uses

func (DebugMessageEventHandler) HandleMessageEvent(event MessageEvent, message []byte, err error, trace ...interface{})

HandleMessageEvent dumps all message events

type DebugSMPEventHandler Uses

type DebugSMPEventHandler struct{}

DebugSMPEventHandler is an SMPEventHandler that dumps all SMPEvents to standard error

func (DebugSMPEventHandler) HandleSMPEvent Uses

func (DebugSMPEventHandler) HandleSMPEvent(event SMPEvent, progressPercent int, question string)

HandleSMPEvent dumps all SMP events

type DebugSecurityEventHandler Uses

type DebugSecurityEventHandler struct{}

DebugSecurityEventHandler is a SecurityEventHandler that dumps all SecurityEvents to standard error

func (DebugSecurityEventHandler) HandleSecurityEvent Uses

func (DebugSecurityEventHandler) HandleSecurityEvent(event SecurityEvent)

HandleSecurityEvent dumps all security events

type ErrorCode Uses

type ErrorCode int

ErrorCode represents an error that can happen during OTR processing

const (
    // ErrorCodeEncryptionError means an error occured while encrypting a message
    ErrorCodeEncryptionError ErrorCode = iota

    // ErrorCodeMessageUnreadable means we received an unreadable encrypted message
    ErrorCodeMessageUnreadable

    // ErrorCodeMessageMalformed means the message sent is malformed
    ErrorCodeMessageMalformed

    // ErrorCodeMessageNotInPrivate means we received an encrypted message when not expecting it
    ErrorCodeMessageNotInPrivate
)

func (ErrorCode) String Uses

func (s ErrorCode) String() string

type ErrorMessageHandler Uses

type ErrorMessageHandler interface {
    // HandleErrorMessage should return a string according to the error event. This string will be concatenated to an OTR header to produce an OTR protocol error message
    HandleErrorMessage(error ErrorCode) []byte
}

ErrorMessageHandler generates error messages for error codes

func CombineErrorMessageHandlers Uses

func CombineErrorMessageHandlers(handlers ...ErrorMessageHandler) ErrorMessageHandler

CombineErrorMessageHandlers creates an ErrorMessageHandler that will call all handlers given to this function. It returns the result of the final handler called

type MessageEvent Uses

type MessageEvent int

MessageEvent define the events used to indicate the messages that need to be sent

const (
    // MessageEventEncryptionRequired is signaled when our policy requires encryption but we are trying to send an unencrypted message.
    MessageEventEncryptionRequired MessageEvent = iota

    // MessageEventEncryptionError is signaled when an error occured while encrypting a message and the message was not sent.
    MessageEventEncryptionError

    // MessageEventConnectionEnded is signaled when we are asked to send a message but the peer has ended the private conversation.
    // At this point the connection should be closed or refreshed.
    MessageEventConnectionEnded

    // MessageEventSetupError will be signaled when a private conversation could not be established. The reason for this will be communicated with the attached error instance.
    MessageEventSetupError

    // MessageEventMessageReflected will be signaled if we received our own OTR messages.
    MessageEventMessageReflected

    // MessageEventMessageSent is signaled when a message is sent after having been queued
    MessageEventMessageSent

    // MessageEventMessageResent is signaled when a message is resent
    MessageEventMessageResent

    // MessageEventReceivedMessageNotInPrivate will be signaled when we receive an encrypted message that we cannot read, because we don't have an established private connection
    MessageEventReceivedMessageNotInPrivate

    // MessageEventReceivedMessageUnreadable will be signaled when we cannot read the received message.
    MessageEventReceivedMessageUnreadable

    // MessageEventReceivedMessageMalformed is signaled when we receive a message that contains malformed data.
    MessageEventReceivedMessageMalformed

    // MessageEventLogHeartbeatReceived is triggered when we received a heartbeat.
    MessageEventLogHeartbeatReceived

    // MessageEventLogHeartbeatSent is triggered when we have sent a heartbeat.
    MessageEventLogHeartbeatSent

    // MessageEventReceivedMessageGeneralError will be signaled when we receive an OTR error from the peer.
    // The message parameter will be passed, containing the error message
    MessageEventReceivedMessageGeneralError

    // MessageEventReceivedMessageUnencrypted is triggered when we receive a message that was sent in the clear when it should have been encrypted.
    // The actual message received will also be passed.
    MessageEventReceivedMessageUnencrypted

    // MessageEventReceivedMessageUnrecognized is triggered when we receive an OTR message whose type we cannot recognize
    MessageEventReceivedMessageUnrecognized

    // MessageEventReceivedMessageForOtherInstance is triggered when we receive and discard a message for another instance
    MessageEventReceivedMessageForOtherInstance
)

func (MessageEvent) String Uses

func (s MessageEvent) String() string

String returns the string representation of the MessageEvent

type MessageEventHandler Uses

type MessageEventHandler interface {
    // HandleMessageEvent should handle and send the appropriate message(s) to the sender/recipient depending on the message events
    HandleMessageEvent(event MessageEvent, message []byte, err error, trace ...interface{})
}

MessageEventHandler handles MessageEvents

func CombineMessageEventHandlers Uses

func CombineMessageEventHandlers(handlers ...MessageEventHandler) MessageEventHandler

CombineMessageEventHandlers creates a MessageEventHandler that will call all handlers given to this function. It ignores nil entries.

type MessagePlaintext Uses

type MessagePlaintext []byte

MessagePlaintext contains regular plaintext to send or receive

type OtrError Uses

type OtrError struct {
    // contains filtered or unexported fields
}

OtrError is an error in the OTR library

func (OtrError) Error Uses

func (oe OtrError) Error() string

type PrivateKey Uses

type PrivateKey interface {
    Parse([]byte) ([]byte, bool)
    Serialize() []byte
    Sign(io.Reader, []byte) ([]byte, error)
    Generate(io.Reader) error
    PublicKey() PublicKey
    IsAvailableForVersion(uint16) bool
}

PrivateKey is a private key used to sign messages

func GenerateMissingKeys Uses

func GenerateMissingKeys(existing [][]byte) ([]PrivateKey, error)

GenerateMissingKeys will look through the existing serialized keys and generate new keys to ensure that the functioning of this version of OTR will work correctly. It will only return the newly generated keys, not the old ones

func ParsePrivateKey Uses

func ParsePrivateKey(in []byte) (index []byte, ok bool, key PrivateKey)

ParsePrivateKey is an algorithm indepedent way of parsing private keys

type PublicKey Uses

type PublicKey interface {
    Parse([]byte) ([]byte, bool)
    Fingerprint() []byte
    Verify([]byte, []byte) ([]byte, bool)

    IsSame(PublicKey) bool
    // contains filtered or unexported methods
}

PublicKey is a public key used to verify signed messages

func ParsePublicKey Uses

func ParsePublicKey(in []byte) (index []byte, ok bool, key PublicKey)

ParsePublicKey is an algorithm independent way of parsing public keys

type ReceivedKeyHandler Uses

type ReceivedKeyHandler interface {
    // ReceivedSymmetricKey will be called when a TLV requesting the use of a symmetric key is received
    ReceivedSymmetricKey(usage uint32, usageData []byte, symkey []byte)
}

ReceivedKeyHandler is an interface that will be invoked when an extra key is received

type SMPEvent Uses

type SMPEvent int

SMPEvent define the events used to indicate status of SMP to the UI

const (
    // SMPEventError means abort the current auth and update the auth progress dialog with progress_percent. This event is only sent when we receive a message for another message state than we are in
    SMPEventError SMPEvent = iota
    // SMPEventAbort means update the auth progress dialog with progress_percent
    SMPEventAbort
    // SMPEventCheated means abort the current auth and update the auth progress dialog with progress_percent
    SMPEventCheated
    // SMPEventAskForAnswer means ask the user to answer the secret question
    SMPEventAskForAnswer
    // SMPEventAskForSecret means prompt the user to enter a shared secret
    SMPEventAskForSecret
    // SMPEventInProgress means update the auth progress dialog with progress_percent
    SMPEventInProgress
    // SMPEventSuccess means update the auth progress dialog with progress_percent
    SMPEventSuccess
    // SMPEventFailure means update the auth progress dialog with progress_percent
    SMPEventFailure
)

func (SMPEvent) String Uses

func (s SMPEvent) String() string

type SMPEventHandler Uses

type SMPEventHandler interface {
    // HandleSMPEvent should update the authentication UI with respect to SMP events
    HandleSMPEvent(event SMPEvent, progressPercent int, question string)
}

SMPEventHandler handles SMPEvents

func CombineSMPEventHandlers Uses

func CombineSMPEventHandlers(handlers ...SMPEventHandler) SMPEventHandler

CombineSMPEventHandlers creates a SMPEventHandler that will call all handlers given to this function. It ignores nil entries.

type SecurityEvent Uses

type SecurityEvent int

SecurityEvent define the events used to indicate changes in security status. In comparison with libotr, this library does not take trust levels into concern for security events

const (
    // GoneInsecure is signalled when we have gone from a secure state to an insecure state
    GoneInsecure SecurityEvent = iota
    // GoneSecure is signalled when we have gone from an insecure state to a secure state
    GoneSecure
    // StillSecure is signalled when we have refreshed the security state but is still in a secure state
    StillSecure
)

func (SecurityEvent) String Uses

func (s SecurityEvent) String() string

String returns the string representation of the SecurityEvent

type SecurityEventHandler Uses

type SecurityEventHandler interface {
    // HandleSecurityEvent is called when a change in security status happens
    HandleSecurityEvent(event SecurityEvent)
}

SecurityEventHandler is an interface for events that are related to changes of security status

func CombineSecurityEventHandlers Uses

func CombineSecurityEventHandlers(handlers ...SecurityEventHandler) SecurityEventHandler

CombineSecurityEventHandlers creates a SecurityEventHandler that will call all handlers given to this function. It ignores nil entries.

type ValidMessage Uses

type ValidMessage []byte

ValidMessage is a message that has gone through fragmentation and is valid to send through the IM client Some encodedMessage instances are validMessage instances, but this depends on the fragmentation size

Directories

PathSynopsis
sexp

Package otr3 imports 25 packages (graph) and is imported by 19 packages. Updated 2019-11-22. Refresh now. Tools for package owners.