[go: up one dir, main page]

omemo

package module
v0.0.0-...-4f52433 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2024 License: BSD-2-Clause Imports: 31 Imported by: 0

README

OMEMO go implementation (aka omemo)

GoDoc Chat License

An OMEMO e2e encryption implementation for melliu.im/xmpp.

To use it in your project, import it (or any of its other packages) like so:

import mellium.im/omemo

If you'd like to contribute to the project, see CONTRIBUTING.md.

License

The package may be used under the terms of the BSD 2-Clause License a copy of which may be found in the file "LICENSE".

Unless you explicitly state otherwise, any contribution submitted for inclusion in the work by you shall be licensed as above, without any additional terms or conditions.

Documentation

Overview

Package omemo implements end-to-end encryption for XMPP.

OMEMO is an end-to-end (e2e) encryption protocol for XMPP based on the Signal Double Ratchet protocol.

Index

Constants

View Source
const (
	NSLegacyDevices = "eu.siacs.conversations.axolotl.devicelist"
	NSLegacyBundles = "eu.siacs.conversations.axolotl.bundles"
	NSDevices       = "urn:xmpp:omemo:2:devices"
	NSBundles       = "urn:xmpp:omemo:2:bundles"
)
View Source
const BOUNARY = `==$`
View Source
const DEFAULT_OMEMO_NAMESPACE = "urn:xmpp:omemo:2"
View Source
const DEVICE_ID = `[^:]+$`

Variables

View Source
var File_message_proto protoreflect.FileDescriptor
View Source
var ZERO_BITS_256 = make([]byte, 256/8)

Functions

func Aes256Decrypt

func Aes256Decrypt(cryptbytes []byte, key []byte, iv []byte, blockSize int) ([]byte, error)

func Aes256Encrypt

func Aes256Encrypt(plaintext string, key []byte, iv []byte, blockSize int) ([]byte, error)

func HkdfSha256

func HkdfSha256(key []byte, length uint32, salt []byte, info []byte) ([]byte, error)

Calculate the Hkdf-Sha-256 hash.

@param key Crypto key

@param length Length of the resulting byte slice

@param info Info for HKDF hasher. Can be `nil`

@param salt Salt for the HKDF hasher. Can be `nil`

func NewDevice

func NewDevice()

func PKCS7Padding

func PKCS7Padding(ciphertext []byte, blockSize int, after int) []byte

shamelessly ripped from https://gist.github.com/yingray/57fdc3264b1927ef0f984b533d63abab TODO

func SplitHkdfSha256

func SplitHkdfSha256(data []byte) ([]byte, []byte, []byte)

Types

type AuthenticatedMessage

type AuthenticatedMessage struct {
	Mac     []byte `protobuf:"bytes,1,opt,name=mac,proto3" json:"mac,omitempty"`
	Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // Byte-encoding of an OMEMOMessage
	// contains filtered or unexported fields
}

func (*AuthenticatedMessage) Descriptor deprecated

func (*AuthenticatedMessage) Descriptor() ([]byte, []int)

Deprecated: Use AuthenticatedMessage.ProtoReflect.Descriptor instead.

func (*AuthenticatedMessage) GetMac

func (x *AuthenticatedMessage) GetMac() []byte

func (*AuthenticatedMessage) GetMessage

func (x *AuthenticatedMessage) GetMessage() []byte

func (*AuthenticatedMessage) ProtoMessage

func (*AuthenticatedMessage) ProtoMessage()

func (*AuthenticatedMessage) ProtoReflect

func (x *AuthenticatedMessage) ProtoReflect() protoreflect.Message

func (*AuthenticatedMessage) Reset

func (x *AuthenticatedMessage) Reset()

func (*AuthenticatedMessage) String

func (x *AuthenticatedMessage) String() string

type BaseCryptoProvider

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

type Bundle

type Bundle struct {
	SPK struct {
		ID   int
		Data []byte
	}
	SPKs   []byte
	IK     []byte
	PreKey []struct {
		ID   int
		Data []byte
	}
}

type CryptoProvider

type CryptoProvider interface {
	RandomBytes(size uint8) ([]byte, error)
	AesGcmEncrypt(plaintext []byte, key []byte, nonce []byte, extra []byte) ([]byte, error)
	AesGcmDecrypt(ciphertext []byte, key []byte, nonce []byte, extra []byte) ([]byte, error)
	UserData() []byte
	SetUserData([]byte)
}

type DefaultCryptoProvider

type DefaultCryptoProvider struct {
	BaseCryptoProvider
}

func (*DefaultCryptoProvider) AesGcmDecrypt

func (c *DefaultCryptoProvider) AesGcmDecrypt(ciphertext []byte, key []byte, nonce []byte, extra []byte) ([]byte, error)

func (*DefaultCryptoProvider) AesGcmEncrypt

func (c *DefaultCryptoProvider) AesGcmEncrypt(plaintext []byte, key []byte, nonce []byte, extra []byte) ([]byte, error)

func (*DefaultCryptoProvider) RandomBytes

func (c *DefaultCryptoProvider) RandomBytes(size uint8) ([]byte, error)

func (*DefaultCryptoProvider) SetUserData

func (c *DefaultCryptoProvider) SetUserData(data []byte)

func (*DefaultCryptoProvider) UserData

func (c *DefaultCryptoProvider) UserData() []byte

type Device

type Device struct {
	ID          int32
	Label       string
	IdentityKey ed25519.PrivateKey
}

Device is the identity of a single OMEMO client.

type Iq

type Iq struct {
	From   string `xml:"from,attr"`
	Type   string `xml:"type,attr"`
	Id     string `xml:"id,attr"`
	SubPub SubPub `xml:"subpubr"`
}

type Jid

type Jid = string

type JidKeysMap

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

func (*JidKeysMap) All

func (j *JidKeysMap) All() map[string]map[uint32]bool

func (*JidKeysMap) Flat

func (j *JidKeysMap) Flat() []flatJidMap

func (*JidKeysMap) Set

func (j *JidKeysMap) Set(jid string, rid uint32, kex bool)

type Key

type Key = t.BKey

type KeyExchange

type KeyExchange struct {
	PkId    uint32                `protobuf:"varint,1,opt,name=pk_id,json=pkId,proto3" json:"pk_id,omitempty"`
	SpkId   uint32                `protobuf:"varint,2,opt,name=spk_id,json=spkId,proto3" json:"spk_id,omitempty"`
	Ik      []byte                `protobuf:"bytes,3,opt,name=ik,proto3" json:"ik,omitempty"`
	Ek      []byte                `protobuf:"bytes,4,opt,name=ek,proto3" json:"ek,omitempty"`
	Message *AuthenticatedMessage `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"`
	// contains filtered or unexported fields
}

func (*KeyExchange) Descriptor deprecated

func (*KeyExchange) Descriptor() ([]byte, []int)

Deprecated: Use KeyExchange.ProtoReflect.Descriptor instead.

func (*KeyExchange) GetEk

func (x *KeyExchange) GetEk() []byte

func (*KeyExchange) GetIk

func (x *KeyExchange) GetIk() []byte

func (*KeyExchange) GetMessage

func (x *KeyExchange) GetMessage() *AuthenticatedMessage

func (*KeyExchange) GetPkId

func (x *KeyExchange) GetPkId() uint32

func (*KeyExchange) GetSpkId

func (x *KeyExchange) GetSpkId() uint32

func (*KeyExchange) ProtoMessage

func (*KeyExchange) ProtoMessage()

func (*KeyExchange) ProtoReflect

func (x *KeyExchange) ProtoReflect() protoreflect.Message

func (*KeyExchange) Reset

func (x *KeyExchange) Reset()

func (*KeyExchange) String

func (x *KeyExchange) String() string

type Message

type Message struct {
	N          uint32 `protobuf:"varint,1,opt,name=n,proto3" json:"n,omitempty"`
	Pn         uint32 `protobuf:"varint,2,opt,name=pn,proto3" json:"pn,omitempty"`
	DhPub      []byte `protobuf:"bytes,3,opt,name=dh_pub,json=dhPub,proto3" json:"dh_pub,omitempty"`
	Ciphertext []byte `protobuf:"bytes,4,opt,name=ciphertext,proto3,oneof" json:"ciphertext,omitempty"`
	// contains filtered or unexported fields
}

func (*Message) Descriptor deprecated

func (*Message) Descriptor() ([]byte, []int)

Deprecated: Use Message.ProtoReflect.Descriptor instead.

func (*Message) GetCiphertext

func (x *Message) GetCiphertext() []byte

func (*Message) GetDhPub

func (x *Message) GetDhPub() []byte

func (*Message) GetN

func (x *Message) GetN() uint32

func (*Message) GetPn

func (x *Message) GetPn() uint32

func (*Message) ProtoMessage

func (*Message) ProtoMessage()

func (*Message) ProtoReflect

func (x *Message) ProtoReflect() protoreflect.Message

func (*Message) Reset

func (x *Message) Reset()

func (*Message) String

func (x *Message) String() string

type MessageContext

type MessageContext struct {
	AuthKey   [32]byte
	SharedKey [32]byte
}

func (*MessageContext) MarshalXML

func (m *MessageContext) MarshalXML(e *xml.Encoder,
	start xml.StartElement) (err error)

basically, skip message context

type OmemoBundle

type OmemoBundle struct {
	DeviceId        string
	SignedPkNode    []OmemoSignedPk      `xml:"signedPreKeyPublic,omitempty"`
	SignatureNodePk string               `xml:"signedPreKeySignature,omitempty"`
	IdentityKeyNode string               `xml:"identityKey,omitempty"`
	PreKeysNode     []OmemoPreKeysPublic `xml:"prekeys>preKeyPublic"`
}

func ImportBundle

func ImportBundle(received string) (*OmemoBundle, error)

Marshall XML into a bundle.

func (*OmemoBundle) GetIdentityKey

func (b *OmemoBundle) GetIdentityKey() ([]byte, error)

Get the pre-signed key based on a key id.

func (*OmemoBundle) GetRandomPreKey

func (b *OmemoBundle) GetRandomPreKey() ([]byte, error)

Get a random pre key

func (*OmemoBundle) GetSignedPreKey

func (b *OmemoBundle) GetSignedPreKey(pre_key_id uint32) ([]byte, error)

Get the pre-signed key based on a key id.

func (*OmemoBundle) SetIdenityKey

func (b *OmemoBundle) SetIdenityKey(data []byte) error

set the identity key

func (*OmemoBundle) SetSignedPreKey

func (b *OmemoBundle) SetSignedPreKey(pre_key_id uint32, data []byte) error

type OmemoEncHeader

type OmemoEncHeader struct {
	Sid  uint32      `xml:"sid,attr,omitempty"`
	Keys []OmemoKeys `xml:"key,omitempty"`
	Iv   string      `xml:"iv"`
}

type OmemoEncKey

type OmemoEncKey struct {
	Rid    uint32 `xml:"rid,omitempty"`
	PreKey bool   `xml:"prekey,omitempty"`
	Value  string `xml:",chardata"`
	Kex    bool   `xml:"kex,omitempty"`
}

func (*OmemoEncKey) ByteValue

func (o *OmemoEncKey) ByteValue() ([]byte, error)

type OmemoEncrypted

type OmemoEncrypted struct {
	Namespace string          `xml:"xmlns,attr"`
	Header    *OmemoEncHeader `xml:"header,omitempty"`
	Payload   string          `xml:"payload"`
}

type OmemoItem

type OmemoItem struct {
	Bundle *OmemoBundle `xml:"bundle,omitempty"`
}

TODO: the *proper* way to do this would be to use an interface. TODO: for now, I'll juste use a "only one can be not null" design.

type OmemoItems

type OmemoItems struct {
	Node string      `xml:"node,attr"`
	Item []OmemoItem `xml:"item,omitempty"`
}

type OmemoKeys

type OmemoKeys struct {
	Jid  string        `xml:"jid,omitempty"`
	Keys []OmemoEncKey `xml:"key,omitempty"`
}

func (*OmemoKeys) UpsertKey

func (kx *OmemoKeys) UpsertKey(rid uint32, kex bool, key_value string) error

type OmemoMessage

type OmemoMessage struct {
	To        string          `xml:"to,attr"`
	From      string          `xml:"from,attr"`
	Id        string          `xml:"id,attr"`
	Encrypted *OmemoEncrypted `xml:"encrypted,omitempty"`
	Context   *MessageContext `xml:"context,omitempty"`
}

func OmemoMessageCreate

func OmemoMessageCreate(sender_device_id uint32, crypto_provider CryptoProvider) (*OmemoMessage, error)

func OmemoMessageFromXml

func OmemoMessageFromXml(x []byte) (*OmemoMessage, error)

func (*OmemoMessage) Decrypt

func (m *OmemoMessage) Decrypt(
	sesh *record.Session,
	sessionBuilder *session.Builder,
	address *protocol.SignalAddress,
	my_jid string,
	my_device_id uint32,
) error

func (*OmemoMessage) Encrypt

func (m *OmemoMessage) Encrypt(
	sender_device_id uint32,
	jid_key_map JidKeysMap,
	pk_id,
	spk_id uint32,
	ik *identity.Key,
	ek ecc.ECPublicKeyable,
	sk Key,
	ad []byte,
	address *protocol.SignalAddress,
	senderParams *ratchet.SenderParameters,
	sessionBuilder *session.Builder,
	sesh *record.Session,
) error

Encrypt the OMEMO message.

@param plaintext The plaintext message, e.g. "Hello, John"

@param sender_device_id The device ID

@param jid_key_map A mapping of JIDs (e.g. `user@domain.com`) to device specifications (e.g. {Rid => 11309, Kex => true}) to encrypt the message.

@param pk_id ID of the prekey from the bundle on the server

@parm spk_id ID of signed prekey from the bundle on the server

@param ik Identity key of the sender

@param ek Ephemeral key of the sender.

@param sk Secret key derived from X3DH

@param ad Associated data dervied from X3DH

func (*OmemoMessage) ToXml

func (m *OmemoMessage) ToXml() ([]byte, error)

func (*OmemoMessage) UpsertMsgOrKex

func (m *OmemoMessage) UpsertMsgOrKex(jid string, rid uint32, kex bool, key_value string) error

type OmemoPreKeysPublic

type OmemoPreKeysPublic struct {
	PreKeyId uint32 `xml:"preKeyId,attr"`
	Value    string `xml:",chardata"`
}

type OmemoSignedPk

type OmemoSignedPk struct {
	SignedPreKeyId uint32 `xml:"signedPreKeyId,attr"`
	Value          string `xml:",chardata"`
}

type Pep

type Pep struct {
	Iq Iq `xml:"iq"`
}

or "personal eventing protocol"

type Publish

type Publish struct {
}

type PublishOption

type PublishOption struct {
}

type Rid

type Rid = uint32

type SubPub

type SubPub struct {
	Publish        Publish         `xml:"publish,attr"`
	PublishOptions []PublishOption `xml:"publish-options"`
}

type XmlPreKeySerializer

type XmlPreKeySerializer struct {
}

func (XmlPreKeySerializer) Deserialize

func (p XmlPreKeySerializer) Deserialize(serializedPreKey []byte) (*record.SignedPreKeyStructure, error)

func (XmlPreKeySerializer) Serialize

func (p XmlPreKeySerializer) Serialize(signedPreKey *record.SignedPreKeyStructure) []byte

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL