e4go: github.com/teserakt-io/e4go Index | Examples | Files | Directories

package e4

import "github.com/teserakt-io/e4go"

Package e4 provides a e4 client implementation and libraries.

It aims to be quick and easy to integrate in IoT devices applications enabling to secure their communications, as well as exposing a way to manage the various keys required.

Protecting and unprotecting messages

Once created, a client provide methods to protect messages before sending them to the broker:

protectedMessage, err := client.ProtectMessage([]byte("secret message"), topicKey)

or unprotecting the messages it receives.

originalMessage, err := client.Unprotect([]byte(protectedMessage, topicKey))

ReceivingTopic and client commands

A special topic (called ReceivingTopic) is reserved to communicate protected commands to the client. Such commands are used to update the client state, like setting a new key for a topic, or renewing its private key. There is nothing particular to be done when receiving a command, just passing its protected form to the Unprotect() method and the client will automatically unprotect and process it (thus returning no unprotected message). See commands.go for the list of available commands and their respective parameters.

Index

Examples

Package Files

client.go commands.go storage.go

Constants

const (
    // RemoveTopic command allows to remove a topic key from the client.
    // It expects a topic hash as argument
    RemoveTopic byte = iota
    // ResetTopics allows to clear out all the topics on a client.
    // It doesn't have any argument
    ResetTopics
    // SetIDKey allows to set the private key of a client.
    // It expects a key as argument
    SetIDKey
    // SetTopicKey allows to add a topic key on the client.
    // It takes a key, followed by a topic hash as arguments.
    SetTopicKey
    // RemovePubKey allows to remove a public key from the client.
    // It takes the ID to be removed as argument
    RemovePubKey
    // ResetPubKeys removes all public keys stored on the client.
    // It expects no argument
    ResetPubKeys
    // SetPubKey allows to set a public key on the client.
    // It takes a public key, followed by an ID as arguments.
    SetPubKey
    // SetC2PubKey replaces the current C2 public key with the newly transmitted one.
    SetC2Key

    // UnknownCommand must stay the last element. It's used to
    // know if a Command is out of range
    UnknownCommand = 0xFF
)

List of supported commands

Variables

var (
    // ErrTopicKeyNotFound occurs when a topic key is missing when encryption/decrypting
    ErrTopicKeyNotFound = errors.New("topic key not found")
    // ErrUnsupportedOperation occurs when trying to manipulate client public keys with a ClientKey not supporting it
    ErrUnsupportedOperation = errors.New("this operation is not supported")
)
var (
    // ErrInvalidCommand is returned when trying to process an unsupported command
    ErrInvalidCommand = errors.New("invalid command")
)

func CmdRemovePubKey Uses

func CmdRemovePubKey(name string) ([]byte, error)

CmdRemovePubKey creates a command to remove the public key identified by given name from the client

func CmdRemoveTopic Uses

func CmdRemoveTopic(topic string) ([]byte, error)

CmdRemoveTopic creates a command to remove the key associated with the topic, from the client

func CmdResetPubKeys Uses

func CmdResetPubKeys() ([]byte, error)

CmdResetPubKeys creates a command to removes all public keys from the client

func CmdResetTopics Uses

func CmdResetTopics() ([]byte, error)

CmdResetTopics creates a command to remove all topic keys stored on the client

func CmdSetC2Key Uses

func CmdSetC2Key(c2PubKey e4crypto.Curve25519PublicKey) ([]byte, error)

CmdSetC2Key creates a command to replace the c2 public key by the given one.

func CmdSetIDKey Uses

func CmdSetIDKey(key []byte) ([]byte, error)

CmdSetIDKey creates a command to set the client private key to the given key

func CmdSetPubKey Uses

func CmdSetPubKey(pubKey e4crypto.Ed25519PublicKey, name string) ([]byte, error)

CmdSetPubKey creates a command to set a given public key, identified by given name on the client

func CmdSetTopicKey Uses

func CmdSetTopicKey(topicKey []byte, topic string) ([]byte, error)

CmdSetTopicKey creates a command to set the given topic key and its corresponding topic, on the client

func TopicForID Uses

func TopicForID(id []byte) string

TopicForID generate the receiving topic that a client should subscribe to in order to receive commands

type Client Uses

type Client interface {
    // ProtectMessage will encrypt the given payload using the key associated to topic.
    // When the client doesn't have a key for this topic, ErrTopicKeyNotFound will be returned.
    // When no errors, the protected cipher bytes are returned
    ProtectMessage(payload []byte, topic string) ([]byte, error)
    // Unprotect attempts to decrypt the given cipher using the topic key.
    // When the client doesn't have a key for this topic, ErrTopicKeyNotFound will be returned.
    // When no errors, the clear payload bytes are returned, unless the protected message was a client command.
    // Message are client commands when received on the client receiving topic. The command will be processed
    // when unprotecting it, making a nil,nil response indicating a success
    Unprotect(protected []byte, topic string) ([]byte, error)
    // IsReceivingTopic returns true when the given topic is the client receiving topics.
    // Message received from this topics will be protected commands, meant to update the client state
    IsReceivingTopic(topic string) bool
    // GetReceivingTopic returns the receiving topic for this client, which will be used to transmit commands
    // allowing to update the client state, like setting a new private key or adding a new topic key.
    GetReceivingTopic() string
    // contains filtered or unexported methods
}

Client defines interface for protecting and unprotecting E4 messages and commands

func LoadClient Uses

func LoadClient(store ReadWriteSeeker) (Client, error)

LoadClient loads a client state from the file system

func NewClient Uses

func NewClient(config ClientConfig, store ReadWriteSeeker) (Client, error)

NewClient creates a new E4 client, working either in symmetric key mode, or public key mode depending the given ClientConfig

config is a ClientConfig, either SymIDAndKey, SymNameAndPassword, PubIDAndKey or PubNameAndPassword store is an e4.ReadWriteSeeker implementation

Code:

f, err := os.OpenFile("/storage/clientID.json", os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
    panic(err)
}
defer f.Close()

client, err := e4.NewClient(&e4.SymIDAndKey{
    ID:  []byte("clientID"),
    Key: e4crypto.RandomKey(),
}, f)
if err != nil {
    panic(err)
}

protectedMessage, err := client.ProtectMessage([]byte("very secret message"), "topic/name")
if err != nil {
    panic(err)
}
fmt.Printf("Protected message: %v", protectedMessage)

Code:

privateKey, err := e4crypto.Ed25519PrivateKeyFromPassword("verySecretPassword")
if err != nil {
    panic(err)
}

c2PubKey, err := curve25519.X25519(e4crypto.RandomKey(), curve25519.Basepoint)
if err != nil {
    panic(err)
}

client, err := e4.NewClient(&e4.PubIDAndKey{
    ID:       []byte("clientID"),
    Key:      privateKey,
    C2PubKey: c2PubKey,
}, e4.NewInMemoryStore(nil))

if err != nil {
    panic(err)
}

protectedMessage, err := client.ProtectMessage([]byte("very secret message"), "topic/name")
if err != nil {
    panic(err)
}
fmt.Printf("Protected message: %v", protectedMessage)

Code:

c2PubKey, err := curve25519.X25519(e4crypto.RandomKey(), curve25519.Basepoint)
if err != nil {
    panic(err)
}

config := &e4.PubNameAndPassword{
    Name:     "clientName",
    Password: "verySecretPassword",
    C2PubKey: c2PubKey,
}
client, err := e4.NewClient(config, e4.NewInMemoryStore(nil))
if err != nil {
    panic(err)
}

// We may need to get the public key derived from the password:
pubKey, err := config.PubKey()
if err != nil {
    panic(err)
}
fmt.Printf("Client public key: %x", pubKey)

protectedMessage, err := client.ProtectMessage([]byte("very secret message"), "topic/name")
if err != nil {
    panic(err)
}
fmt.Printf("Protected message: %v", protectedMessage)

Code:

client, err := e4.NewClient(&e4.SymIDAndKey{
    ID:  []byte("clientID"),
    Key: e4crypto.RandomKey(),
}, e4.NewInMemoryStore(nil))
if err != nil {
    panic(err)
}

protectedMessage, err := client.ProtectMessage([]byte("very secret message"), "topic/name")
if err != nil {
    panic(err)
}
fmt.Printf("Protected message: %v", protectedMessage)

Code:

client, err := e4.NewClient(&e4.SymNameAndPassword{
    Name:     "clientName",
    Password: "verySecretPassword",
}, e4.NewInMemoryStore(nil))
if err != nil {
    panic(err)
}

protectedMessage, err := client.ProtectMessage([]byte("very secret message"), "topic/name")
if err != nil {
    panic(err)
}
fmt.Printf("Protected message: %v", protectedMessage)

type ClientConfig Uses

type ClientConfig interface {
    // contains filtered or unexported methods
}

ClientConfig defines an interface for client configuration

type PubIDAndKey Uses

type PubIDAndKey struct {
    ID       []byte
    Key      e4crypto.Ed25519PrivateKey
    C2PubKey e4crypto.Curve25519PublicKey
}

PubIDAndKey defines a configuration to create an E4 client in public key mode from an ID, an ed25519 private key, and a curve25519 public key.

type PubNameAndPassword Uses

type PubNameAndPassword struct {
    Name     string
    Password string
    C2PubKey e4crypto.Curve25519PublicKey
}

PubNameAndPassword defines a configuration to create an E4 client in public key mode from a name, a password and a curve25519 public key. The password must contains at least 16 characters.

func (*PubNameAndPassword) PubKey Uses

func (np *PubNameAndPassword) PubKey() (e4crypto.Ed25519PublicKey, error)

PubKey returns the ed25519.PublicKey derived from the password

type ReadWriteSeeker Uses

type ReadWriteSeeker interface {
    io.ReadWriteSeeker
}

ReadWriteSeeker is a redefinition of io.ReadWriteSeeker to ensure that gomobile bindings still get generated without incompatible type removals

func NewInMemoryStore Uses

func NewInMemoryStore(buf []byte) ReadWriteSeeker

NewInMemoryStore creates a new ReadWriteSeeker in memory

type SymIDAndKey Uses

type SymIDAndKey struct {
    ID  []byte
    Key []byte
}

SymIDAndKey defines a configuration to create an E4 client in symmetric key mode from an ID and a symmetric key

type SymNameAndPassword Uses

type SymNameAndPassword struct {
    Name     string
    Password string
}

SymNameAndPassword defines a configuration to create an E4 client in symmetric key mode from a name and a password. The password must contains at least 16 characters.

Directories

PathSynopsis
cryptoPackage crypto defines the cryptographic functions used in E4
keysPackage keys holds E4 key material implementations.

Package e4 imports 14 packages (graph). Updated 2020-03-17. Refresh now. Tools for package owners.