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
- func CreateAsymKeys() *ecdsa.PrivateKey
- func CreateEcdsaSignature(payload []byte, privateKey *ecdsa.PrivateKey) string
- func CreateJWSSignature(payload string, privateKey *ecdsa.PrivateKey) (string, error)
- func DecryptMessage(serialized string, privateKey *ecdsa.PrivateKey) (message string, isEncrypted bool, err error)
- func EncryptMessage(message string, publicKey *ecdsa.PublicKey) (serialized string, err error)
- func PrivateKeyFromPem(pemEncodedPriv string) *ecdsa.PrivateKey
- func PrivateKeyToPem(privateKey *ecdsa.PrivateKey) string
- func PublicKeyFromPem(pemEncodedPub string) *ecdsa.PublicKey
- func PublicKeyToPem(publicKey *ecdsa.PublicKey) string
- func SignIdentity(publicIdent *types.PublisherIdentityMessage, privKey *ecdsa.PrivateKey)
- func VerifyEcdsaSignature(payload []byte, signatureB64urlEncoded string, publicKey *ecdsa.PublicKey) error
- func VerifyIdentitySignature(ident *types.PublisherIdentityMessage, pubKey *ecdsa.PublicKey) error
- func VerifyJWSMessage(message string, publicKey *ecdsa.PublicKey) (payload string, err error)
- func VerifySenderJWSSignature(rawMessage string, object interface{}, ...) (isSigned bool, err error)
- type DummyMessenger
- func (messenger *DummyMessenger) Connect(lastWillAddress string, lastWillValue string) error
- func (messenger *DummyMessenger) Disconnect()
- func (messenger *DummyMessenger) FindLastPublication(addr string) (message string)
- func (messenger *DummyMessenger) GetDomain() string
- func (messenger *DummyMessenger) NrPublications() int
- func (messenger *DummyMessenger) OnReceive(address string, message string)
- func (messenger *DummyMessenger) Publish(address string, retained bool, message string) error
- func (messenger *DummyMessenger) Subscribe(address string, onMessage func(address string, message string) error)
- func (messenger *DummyMessenger) Unsubscribe(address string, onMessage func(address string, message string) error)
- type ECDSASignature
- type IMessenger
- type MessageSigner
- func (signer *MessageSigner) DecodeMessage(rawMessage string, object interface{}) (isEncrypted bool, isSigned bool, err error)
- func (signer *MessageSigner) PublishEncrypted(address string, retained bool, payload string, publicKey *ecdsa.PublicKey) error
- func (signer *MessageSigner) PublishObject(address string, retained bool, object interface{}, ...) error
- func (signer *MessageSigner) PublishSigned(address string, retained bool, payload string) error
- func (signer *MessageSigner) SetSignMessages(sign bool)
- func (signer *MessageSigner) SignMessages() bool
- func (signer *MessageSigner) Subscribe(address string, handler func(address string, message string) error)
- func (signer *MessageSigner) Unsubscribe(address string, handler func(address string, message string) error)
- func (signer *MessageSigner) VerifySignedMessage(rawMessage string, object interface{}) (isSigned bool, err error)
- type MessengerConfig
- type MqttMessenger
- func (messenger *MqttMessenger) Connect(lastWillAddress string, lastWillValue string) error
- func (messenger *MqttMessenger) Disconnect()
- func (messenger *MqttMessenger) Publish(address string, retained bool, message string) error
- func (messenger *MqttMessenger) PublishRaw(address string, retained bool, message string) error
- func (messenger *MqttMessenger) Subscribe(address string, onMessage func(address string, message string) error)
- func (messenger *MqttMessenger) Unsubscribe(address string, onMessage func(address string, message string) error)
- type Subscription
- type TopicSubscription
Constants ¶
const ConnectionTimeoutSec = 20
ConnectionTimeoutSec constant with connection and reconnection timeouts
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 ¶
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 ¶
PublicKeyFromPem converts a ascii encoded public key into a ECDSA public key
func PublicKeyToPem ¶
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 ¶
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 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