messaging

package
v0.0.0-...-476b4f6 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2020 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package messaging - Dummy in-memory messenger for testing

Package messaging - Interface of messengers for publishers and subscribers

Package messaging for signing and encryption of messages

Package messaging - Publish and Subscribe to message using the MQTT message bus

Package messaging for handling encryption and signing keys

Index

Constants

View Source
const ConnectionTimeoutSec = 20

ConnectionTimeoutSec constant with connection and reconnection timeouts

View Source
const TLSPort = 8883

TLSPort is the default secure port to connect to mqtt

Variables

This section is empty.

Functions

func CreateAsymKeys

func CreateAsymKeys() *ecdsa.PrivateKey

CreateAsymKeys creates a asymmetric key set Returns a private key that contains its associated public key

func CreateEcdsaSignature

func CreateEcdsaSignature(payload []byte, privateKey *ecdsa.PrivateKey) string

CreateEcdsaSignature creates a ECDSA256 signature from the payload using the provided private key This returns a base64url encoded signature

func CreateJWSSignature

func CreateJWSSignature(payload string, privateKey *ecdsa.PrivateKey) (string, error)

CreateJWSSignature signs the payload using JSE ES256 and return the JSE compact serialized message

func DecryptMessage

func DecryptMessage(serialized string, privateKey *ecdsa.PrivateKey) (message string, isEncrypted bool, err error)

DecryptMessage deserializes and decrypts the message using JWE This returns the decrypted message, or the input message if the message was not encrypted

func EncryptMessage

func EncryptMessage(message string, publicKey *ecdsa.PublicKey) (serialized string, err error)

EncryptMessage encrypts and serializes the message using JWE

func PrivateKeyFromPem

func PrivateKeyFromPem(pemEncodedPriv string) *ecdsa.PrivateKey

PrivateKeyFromPem converts PEM encoded private keys into a ECDSA object for use in the application See also PrivateKeyToPem for the opposite. Returns nil if the encoded pem source isn't a pem format

func PrivateKeyToPem

func PrivateKeyToPem(privateKey *ecdsa.PrivateKey) string

PrivateKeyToPem converts a private key into their PEM encoded ascii format see also https://stackoverflow.com/questions/21322182/how-to-store-ecdsa-private-key-in-go

func PublicKeyFromPem

func PublicKeyFromPem(pemEncodedPub string) *ecdsa.PublicKey

PublicKeyFromPem converts a ascii encoded public key into a ECDSA public key

func PublicKeyToPem

func PublicKeyToPem(publicKey *ecdsa.PublicKey) string

PublicKeyToPem converts a public key into PEM encoded ascii format See also PublicKeyFromPem for its counterpart

func SignIdentity

func SignIdentity(publicIdent *types.PublisherIdentityMessage, privKey *ecdsa.PrivateKey)

SignIdentity updates the base64URL encoded ECDSA256 signature of the public identity

func VerifyEcdsaSignature

func VerifyEcdsaSignature(payload []byte, signatureB64urlEncoded string, publicKey *ecdsa.PublicKey) error

VerifyEcdsaSignature the payload using the base64url encoded signature and public key payload is any raw data signatureB64urlEncoded is the ecdsa 256 URL encoded signature Intended for signing an object like the publisher identity. Use VerifyJWSMessage for verifying JWS signed messages.

func VerifyIdentitySignature

func VerifyIdentitySignature(ident *types.PublisherIdentityMessage, pubKey *ecdsa.PublicKey) error

VerifyIdentitySignature verifies a base64URL encoded ECDSA256 signature in the identity against the identity itself using the sender's public key.

func VerifyJWSMessage

func VerifyJWSMessage(message string, publicKey *ecdsa.PublicKey) (payload string, err error)

VerifyJWSMessage verifies a signed message and returns its payload The message is a JWS encoded string. The public key of the sender is needed to verify the message.

Intended for testing, as the application uses VerifySenderJWSSignature instead.

func VerifySenderJWSSignature

func VerifySenderJWSSignature(rawMessage string, object interface{}, getPublicKey func(address string) *ecdsa.PublicKey) (isSigned bool, err error)

VerifySenderJWSSignature verifies if a message is JWS signed. If signed then the signature is verified using the 'Sender' or 'Address' attributes to determine the public key to verify with. To verify correctly, the sender has to be a known publisher and verified with the DSS.

object MUST be a pointer to the type otherwise unmarshal fails.

getPublicKey is a lookup function for providing the public key from the given sender address.

it should only provide a public key if the publisher is known and verified by the DSS, or
if this zone does not use a DSS (publisher are protected through message bus ACLs)
If not provided then signature verification will succeed.

The rawMessage is json unmarshalled into the given object.

This returns a flag if the message was signed and if so, an error if the verification failed

Types

type DummyMessenger

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

DummyMessenger that implements IMessenger

func NewDummyMessenger

func NewDummyMessenger(config *MessengerConfig) *DummyMessenger

NewDummyMessenger provides a messenger for messages that go no.where...

func (*DummyMessenger) Connect

func (messenger *DummyMessenger) Connect(lastWillAddress string, lastWillValue string) error

Connect the messenger

func (*DummyMessenger) Disconnect

func (messenger *DummyMessenger) Disconnect()

Disconnect gracefully disconnects the messenger

func (*DummyMessenger) FindLastPublication

func (messenger *DummyMessenger) FindLastPublication(addr string) (message string)

FindLastPublication with the given address

func (*DummyMessenger) GetDomain

func (messenger *DummyMessenger) GetDomain() string

GetDomain returns the domain in which this messenger operates This is provided via the messenger config file or defaults to types.LocalDomainID

func (*DummyMessenger) NrPublications

func (messenger *DummyMessenger) NrPublications() int

NrPublications returns the number of received publications

func (*DummyMessenger) OnReceive

func (messenger *DummyMessenger) OnReceive(address string, message string)

OnReceive function to simulate a received message

func (*DummyMessenger) Publish

func (messenger *DummyMessenger) Publish(address string, retained bool, message string) error

Publish a message address is the MQTT address to send to retained (ignored) message JSON text or raw message base64 encoded text

func (*DummyMessenger) Subscribe

func (messenger *DummyMessenger) Subscribe(
	address string, onMessage func(address string, message string) error)

Subscribe to a message by address

func (*DummyMessenger) Unsubscribe

func (messenger *DummyMessenger) Unsubscribe(
	address string, onMessage func(address string, message string) error)

Unsubscribe an address and handler

type ECDSASignature

type ECDSASignature struct {
	R, S *big.Int
}

ECDSASignature ...

type IMessenger

type IMessenger interface {

	// Connect the messenger.
	// This contains the last-will & testament information which is useful to inform subscribers
	//  when a publisher is unintentionally disconnected. Non MQTT busses can replace this with
	// their equivalent if available. Subscribers-only leave this empty.
	//
	// lastWillAddress optional last will & testament address for publishing device state
	//                 on accidental disconnect. Subscribers use "" to ignore.
	// lastWillValue payload to use with the last will publication
	Connect(lastWillAddress string, lastWillValue string) error

	// Gracefully disconnect the messenger and unsubscribe to all subscribed messages.
	// This will prevent the LWT publication so publishers must publish a graceful disconnect
	// message.
	Disconnect()

	// Publish a message. The publisher must sign and optionally encrypt the message before
	// publishing, using the Signing method specified in the config.
	//  address to subscribe to as per IoTDomain standard
	//  retained to have MQTT persists the last message
	//  message is a serialized message to send
	Publish(address string, retained bool, message string) error

	// Subscribe to a message. The subscriber must handle message decryption and signing verification.
	//  address to subscribe to with support for wildcards '+' and '#'. Non MQTT busses must convert to equivalent
	//  onMessage callback is invoked when a message on this address is received
	// Multiple subscriptions for the same address is supported.
	Subscribe(address string, onMessage func(address string, message string) error)

	// Unsubscribe from a previously subscribed address.
	// If onMessage is nil then all subscriptions with the address will be removed
	Unsubscribe(address string, onMessage func(address string, message string) error)
}

IMessenger interface for messenger implementations

func NewMessenger

func NewMessenger(messengerConfig *MessengerConfig) IMessenger

NewMessenger creates a new messenger instance Create a messenger instance using configuration setting:

"DummyMessenger" (default)
MQTTMessenger, requires server, login and credentials properties set

config holds the messenger configuration. If no server is given, 'localhost' will be used.

type MessageSigner

type MessageSigner struct {
	// GetPublicKey when available is used in mess to verify signature
	GetPublicKey func(address string) *ecdsa.PublicKey // must be a variable
	// contains filtered or unexported fields
}

MessageSigner for signing and verifying of signed and encrypted messages

func NewMessageSigner

func NewMessageSigner(messenger IMessenger, signingKey *ecdsa.PrivateKey,
	getPublicKey func(address string) *ecdsa.PublicKey,
) *MessageSigner

NewMessageSigner creates a new instance for signing and verifying published messages If getPublicKey is not provided, verification of signature is skipped

func (*MessageSigner) DecodeMessage

func (signer *MessageSigner) DecodeMessage(rawMessage string, object interface{}) (isEncrypted bool, isSigned bool, err error)

DecodeMessage decrypts the message and verifies the sender signature . The sender and signer of the message is contained the message 'sender' field. If the Sender field is missing then the 'address' field is used as sender. object must hold the expected message type to decode the json message containging the sender info

func (*MessageSigner) PublishEncrypted

func (signer *MessageSigner) PublishEncrypted(
	address string, retained bool, payload string, publicKey *ecdsa.PublicKey) error

PublishEncrypted sign and encrypts the payload and publish the resulting message on the given address Signing only happens if the publisher's signingMethod is set to SigningMethodJWS

func (*MessageSigner) PublishObject

func (signer *MessageSigner) PublishObject(address string, retained bool, object interface{}, encryptionKey *ecdsa.PublicKey) error

PublishObject encapsulates the message object in a payload, signs the message, and sends it.

If an encryption key is provided then the signed message will be encrypted.
The object to publish will be marshalled to JSON and signed by this publisher

func (*MessageSigner) PublishSigned

func (signer *MessageSigner) PublishSigned(
	address string, retained bool, payload string) error

PublishSigned sign the payload and publish the resulting message on the given address Signing only happens if the publisher's signingMethod is set to SigningMethodJWS

func (*MessageSigner) SetSignMessages

func (signer *MessageSigner) SetSignMessages(sign bool)

SetSignMessages enables or disables message signing. Intended for testing.

func (*MessageSigner) SignMessages

func (signer *MessageSigner) SignMessages() bool

SignMessages returns whether messages MUST be signed on sending or receiving

func (*MessageSigner) Subscribe

func (signer *MessageSigner) Subscribe(
	address string,
	handler func(address string, message string) error)

Subscribe to messages on the given address

func (*MessageSigner) Unsubscribe

func (signer *MessageSigner) Unsubscribe(
	address string,
	handler func(address string, message string) error)

Unsubscribe to messages on the given address

func (*MessageSigner) VerifySignedMessage

func (signer *MessageSigner) VerifySignedMessage(rawMessage string, object interface{}) (isSigned bool, err error)

VerifySignedMessage parses and verifies the message signature as per standard, the sender and signer of the message is in the message 'Sender' field. If the Sender field is missing then the 'address' field contains the publisher.

or 'address' field

type MessengerConfig

type MessengerConfig struct {
	ClientID  string `yaml:"clientid,omitempty"`  // optional connect ID, must be unique. Default is generated.
	Domain    string `yaml:"domain,omitempty"`    // Domain to be used by all publishers
	Login     string `yaml:"login"`               // messenger login name
	Port      uint16 `yaml:"port,omitempty"`      // optional port, default is 8883 for TLS
	Password  string `yaml:"credentials"`         // messenger login credentials
	PubQos    byte   `yaml:"pubqos,omitempty"`    // publishing QOS 0-2. Default=0
	Server    string `yaml:"server"`              // Message bus server/broker hostname or ip address, required
	Signing   bool   `yaml:"signing,omitempty"`   // Message signing to be used by all publishers.
	SubQos    byte   `yaml:"subqos,omitempty"`    // Subscription QOS 0-2. Default=0
	Messenger string `yaml:"messenger,omitempty"` // Messenger client type: "DummyMessenger" (default) or "MQTTMessenger"
}

MessengerConfig with configuration of a messenger

type MqttMessenger

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

MqttMessenger that implements IMessenger

func NewMqttMessenger

func NewMqttMessenger(config *MessengerConfig) *MqttMessenger

NewMqttMessenger creates a new MQTT messenger instance

func (*MqttMessenger) Connect

func (messenger *MqttMessenger) Connect(lastWillAddress string, lastWillValue string) error

Connect to the MQTT broker and set the LWT If a previous connection exists then it is disconnected first. This publishes the LWT on the address baseTopic/nodeHWID/$state. @param lastWillTopic optional last will and testament address for publishing device state on accidental disconnect.

Use "" to ignore LWT feature.

@param lastWillValue to use as the last will

func (*MqttMessenger) Disconnect

func (messenger *MqttMessenger) Disconnect()

Disconnect from the MQTT broker and unsubscribe from all addresss and set device state to disconnected

func (*MqttMessenger) Publish

func (messenger *MqttMessenger) Publish(address string, retained bool, message string) error

Publish value using the device address as base address to publish on. retained to have the broker retain the address value payload is converted to string if it isn't a byte array, as Paho doesn't handle int and bool

func (*MqttMessenger) PublishRaw

func (messenger *MqttMessenger) PublishRaw(address string, retained bool, message string) error

PublishRaw message

func (*MqttMessenger) Subscribe

func (messenger *MqttMessenger) Subscribe(
	address string, onMessage func(address string, message string) error)

Subscribe to a address Subscribers are automatically resubscribed after the connection is restored If no connection exists, then subscriptions are stored until a connection is established. address: address to subscribe to. This can contain wildcards. qos: Quality of service for subscription: 0, 1, 2 handler: callback handler.

func (*MqttMessenger) Unsubscribe

func (messenger *MqttMessenger) Unsubscribe(
	address string, onMessage func(address string, message string) error)

Unsubscribe an address and handler if handler is nil then only the address needs to match

type Subscription

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

Subscription to messages

type TopicSubscription

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

TopicSubscription holds subscriptions to restore after disconnect

Jump to

Keyboard shortcuts

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