broadcast

package
v0.0.9 Latest Latest
Warning

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

Go to latest
Published: Dec 6, 2023 License: BSD-2-Clause Imports: 32 Imported by: 16

Documentation

Index

Constants

View Source
const (

	// NameMinChars is the minimum number of UTF-8 characters allowed in a
	// channel name.
	NameMinChars = 3 // 3 characters

	// NameMaxChars is the maximum number of UTF-8 characters allowed in a
	// channel name.
	NameMaxChars = 24 // 24 characters

	// DescriptionMaxChars is the maximum number of UTF-8 characters allowed in
	// a channel description.
	DescriptionMaxChars = 144 // 144 characters
)
View Source
const (

	// MaxUsesKey is the key used to save max uses in a URL. The value is
	// expected to be a positive integer.
	MaxUsesKey = "m"
)

Names for keys in the URL.

Variables

View Source
var (
	// ErrSecretSizeIncorrect indicates an incorrect sized secret.
	ErrSecretSizeIncorrect = errors.New(
		"NewChannelID secret must be 32 bytes long.")

	// ErrSaltSizeIncorrect indicates an incorrect sized salt.
	ErrSaltSizeIncorrect = errors.New(
		"NewChannelID salt must be 32 bytes long.")

	// ErrMalformedPrettyPrintedChannel indicates the channel description blob
	// was malformed.
	ErrMalformedPrettyPrintedChannel = errors.New(
		"Malformed pretty printed channel.")

	// MinNameCharLenErr is returned when the name is shorter than the minimum
	// character limit.
	MinNameCharLenErr = errors.Errorf(
		"name cannot be shorter than %d characters", NameMinChars)

	// MaxNameCharLenErr is returned when the name is longer than the maximum
	// character limit.
	MaxNameCharLenErr = errors.Errorf(
		"name cannot be longer than %d characters", NameMaxChars)

	// NameInvalidCharErr is returned when the name contains disallowed
	// characters.
	NameInvalidCharErr = errors.New("name contains disallowed characters")

	// MaxDescriptionCharLenErr is returned when the description is longer than
	// the maximum character limit.
	MaxDescriptionCharLenErr = errors.Errorf(
		"description cannot be longer than %d characters", DescriptionMaxChars)

	// InvalidPrivacyLevelErr is returned when the PrivacyLevel is not one of
	// the valid chooses.
	InvalidPrivacyLevelErr = errors.New("invalid privacy Level")
)

Error messages.

View Source
var ErrPayloadTooBig = errors.New("cannot symmetrically encrypt the " +
	"payload, it is too large")

ErrPayloadTooBig is returned if the payload is too large

Functions

func DecodeSizedBroadcast

func DecodeSizedBroadcast(data []byte) ([]byte, error)

DecodeSizedBroadcast decodes the data into its original payload stripping off extraneous padding.

func ExportPrivateKey

func ExportPrivateKey(channelID *id.ID, privKey rsa.PrivateKey,
	encryptionPassword string, csprng io.Reader) ([]byte, error)

ExportPrivateKey exports the channel's RSA private key into a portable encrypted string that can be used to restore it later.

Each call to ExportPrivateKey produces a different encrypted packet regardless if the same password is used for the same channel. It cannot be determined which channel the payload is for nor that two payloads are for the same channel.

The passwords between each call are not related. They can be the same or different with no adverse impact on the security properties.

func ExportPrivateKeyCustomParams

func ExportPrivateKeyCustomParams(channelID *id.ID, privKey rsa.PrivateKey,
	encryptionPassword string, params backup.Params, csprng io.Reader) (
	[]byte, error)

ExportPrivateKeyCustomParams exports the channel's RSA private key into a portable encrypted string that can be used to restore it later using custom Argon 2 parameters.

func GetSizedBroadcastSize

func GetSizedBroadcastSize(data []byte) uint16

GetSizedBroadcastSize returns the size of the sized broadcast, used for testing

func HashPubKey

func HashPubKey(pub rsa.PublicKey) []byte

HashPubKey is used to compute the hash of the RSA Public Key

func HashSecret

func HashSecret(secret []byte) []byte

HashSecret secret is hashed first so that we can share all the inputs to the hkdf without giving out the secret.

func HashURLPassword

func HashURLPassword(password string) []byte

HashURLPassword will hash the password given by Channel.ShareURL.

func ImportPrivateKey

func ImportPrivateKey(
	encryptionPassword string, data []byte) (*id.ID, rsa.PrivateKey, error)

ImportPrivateKey returns the channel ID and private RSA key in the encrypted portable string.

func MaxSizedBroadcastPayloadSize

func MaxSizedBroadcastPayloadSize(outerPayloadSize int) int

MaxSizedBroadcastPayloadSize returns the maximum size of a payload that can fit in a sized broadcast message for the given maximum cMix message payload size.

func NewChannelID

func NewChannelID(name, description string, level PrivacyLevel,
	created time.Time, salt, rsaPubHash, secretHash []byte) (*id.ID, error)

NewChannelID creates a new channel id.ID with a type id.User.

The 32-byte identity is derived as described below:

intermediary = H(name | description | level | created | salt | rsaPubHash | hashedSecret)
identityBytes = HKDF(intermediary, salt, hkdfInfo)

func NewSizedBroadcast

func NewSizedBroadcast(
	outerPayloadSize int, payload []byte, rng io.Reader) ([]byte, error)

NewSizedBroadcast creates a new broadcast payload of size maxPayloadSize that contains the given payload so that it fits completely inside a broadcasted cMix message payload. The length of the payload is stored internally and used to strip extraneous padding when decoding the payload.

The maxPayloadSize is the maximum size of the resulting payload. Returns an error when the provided payload cannot fit in the max payload size.

func NewSymmetricKey

func NewSymmetricKey(name, description string, level PrivacyLevel,
	creation time.Time, salt, rsaPubHash, secret []byte) ([]byte, error)

NewSymmetricKey generates a new symmetric channel key, which is derived like this:

intermediary = H(name | description | level | created | rsaPubHash | hashedSecret | salt)
key = HKDF(secret, intermediary, hkdfInfo)

func VerifyDescription

func VerifyDescription(description string) error

VerifyDescription verifies that the description is a valid channel description.

func VerifyName

func VerifyName(name string) error

VerifyName verifies that the name is a valid channel name.

Types

type Channel

type Channel struct {
	ReceptionID *id.ID
	Name        string
	Description string

	// Determines the amount of information displayed as plaintext vs encrypted
	// when sharing channel information.
	//
	// When sharing via a URL comes in one of three forms based on the privacy
	// Level set when generating the channel. Each privacy Level hides more
	// information than the last with the lowest Level revealing everything and
	// the highest Level revealing nothing. For any Level above the lowest, a
	// password is returned, which will be required when decoding the URL.
	Level PrivacyLevel

	// Time the channel is created. It is used as a hint as to when to start
	// picking up messages. Note that this is converted to Unix nano (int64) for
	// all processing and transportation.
	Created time.Time

	Salt            []byte
	RsaPubKeyHash   []byte
	RsaPubKeyLength int
	RSASubPayloads  int
	Secret          []byte
	// contains filtered or unexported fields
}

Channel is a multicast communication channel that retains the various privacy notions that this mix network provides.

func DecodeInviteURL

func DecodeInviteURL(url string, password []byte) (*Channel, error)

DecodeInviteURL decodes the given URL to a Channel. If the channel is Private or Secret, then a password is required. Otherwise, an error is returned.

This should be used for invite URLs, and the user should pass in a hash of the password, rather than the plain password (see HashURLPassword).

func DecodeShareURL

func DecodeShareURL(url, password string) (*Channel, error)

DecodeShareURL decodes the given URL to a Channel. If the channel is Private or Secret, then a password is required. Otherwise, an error is returned.

This should be used for share URLs only. The password passed in should be exactly what is returned from Channel.ShareURL.

func NewChannel

func NewChannel(name, description string, level PrivacyLevel,
	packetPayloadLength int, rng csprng.Source) (*Channel, rsa.PrivateKey, error)

NewChannel creates a new channel with a variable RSA key size calculated based off of recommended security parameters.

The name cannot be more than NameMaxChars characters long and the description cannot be more than DescriptionMaxChars characters long.

func NewChannelFromPrettyPrint

func NewChannelFromPrettyPrint(p string) (*Channel, error)

NewChannelFromPrettyPrint creates a new Channel given a valid pretty printed Channel serialization generated using the Channel.PrettyPrint method.

func NewChannelVariableKeyUnsafe

func NewChannelVariableKeyUnsafe(name, description string, level PrivacyLevel,
	created time.Time, packetPayloadLength int, rng csprng.Source) (
	*Channel, rsa.PrivateKey, error)

NewChannelVariableKeyUnsafe creates a new channel with a variable RSA key size calculated to optimally use space in the packer.

Do not use this function unless you know what you are doing.

packetPayloadLength is in bytes. maxKeySizeBits is the length, in bits, of an RSA key defining the channel in bits. It must be divisible by 8.

func UnmarshalChannel

func UnmarshalChannel(data []byte) (*Channel, error)

UnmarshalChannel JSON marshals a Channel.

func (*Channel) DecryptRSAToPrivate

func (c *Channel) DecryptRSAToPrivate(private rsa.PrivateKey, payload []byte,
	mac []byte, nonce format.Fingerprint) ([]byte, error)

DecryptRSAToPrivate decrypts an RSAToPublic message, dealing with both the symmetric and asymmetric components.

It will reject messages if they are not encrypted with the channel's public key.

func (*Channel) DecryptRSAToPublic

func (c *Channel) DecryptRSAToPublic(payload, mac []byte,
	nonce format.Fingerprint) (decrypted, innerCiphertext []byte, err error)

DecryptRSAToPublic decrypts an RSAToPublic message, dealing with both the symmetric and asymmetric components.

It will reject messages if they are not encrypted with the channel's public key.

func (*Channel) DecryptRSAToPublicInner

func (c *Channel) DecryptRSAToPublicInner(innerCiphertext []byte) ([]byte, error)

DecryptRSAToPublicInner decrypts the inner ciphertext found inside an RSAToPublic message.

This is the inner decryption function for DecryptRSAToPublic. It should only be called in special cases to decrypt a message that has already had the first layer of encryption removed.

func (*Channel) DecryptSymmetric

func (c *Channel) DecryptSymmetric(encryptedPayload, mac []byte,
	nonce format.Fingerprint) ([]byte, error)

DecryptSymmetric symmetrically decrypts the payload with the key after padding.

func (*Channel) EncryptRSAToPrivate

func (c *Channel) EncryptRSAToPrivate(payload []byte, pubkey rsa.PublicKey,
	outerPayloadSize int, rng csprng.Source) (
	doubleEncryptedPayload, mac []byte, nonce format.Fingerprint, err error)

EncryptRSAToPrivate encrypts the given plaintext with the given RSA public key. The payload must not be longer than Channel.GetRSAToPrivateMessageLength()

func (*Channel) EncryptRSAToPublic

func (c *Channel) EncryptRSAToPublic(payload []byte, privKey rsa.PrivateKey,
	outerPayloadSize int, csprng csprng.Source) (singleEncryptedPayload,
	doubleEncryptedPayload, mac []byte, nonce format.Fingerprint, err error)

EncryptRSAToPublic encrypts the payload with the private key. The payload must not be longer than Channel.GetRSAToPublicMessageLength().

symmetric{pubkey | (rsa{p[0]} | rsa{p[1]} | ... | rsa0{p[n]}) | padding}

func (*Channel) EncryptSymmetric

func (c *Channel) EncryptSymmetric(payload []byte, outerPayloadSize int,
	csprng csprng.Source) (encryptedPayload, mac []byte,
	nonce format.Fingerprint, err error)

EncryptSymmetric symmetrically encrypts the payload with the key after padding.

The payload must not be longer than Channel.GetMaxSymmetricPayloadSize.

func (*Channel) GetMaxSymmetricPayloadSize

func (c *Channel) GetMaxSymmetricPayloadSize(outerPayloadSize int) int

GetMaxSymmetricPayloadSize returns the maximum size that a symmetric payload can be based upon the size of the packet it must fit in

func (*Channel) GetRSAToPrivateMessageLength

func (c *Channel) GetRSAToPrivateMessageLength() (size int, numSubPayloads int,
	subPayloadSize int)

GetRSAToPrivateMessageLength returns the size of the internal payload for RSAtoPublic encrypted messages. It returns the total size, the number of sub-payloads, and the size of each sub-payloads.

func (*Channel) GetRSAToPublicMessageLength

func (c *Channel) GetRSAToPublicMessageLength() (size int, numSubPayloads int,
	subPayloadSize int)

GetRSAToPublicMessageLength returns the size of the internal payload for RSAtoPublic encrypted messages. It returns the total size, the number of sub-payloads, and the size of each sub-payloads

func (*Channel) IsPublicKey

func (c *Channel) IsPublicKey(publicKey rsa.PublicKey) bool

IsPublicKey returns true if the passed public key is the public key for the given channel

func (*Channel) Marshal

func (c *Channel) Marshal() ([]byte, error)

Marshal serialises the Channel into JSON.

func (*Channel) PrettyPrint

func (c *Channel) PrettyPrint() string

PrettyPrint prints a human-readable serialization of this Channel that can b copy and pasted.

Example:

<Speakeasy-v3:Test_Channel|description:Channel description.|level:Public|created:1666718081766741100|secrets:+oHcqDbJPZaT3xD5NcdLY8OjOMtSQNKdKgLPmr7ugdU=|rCI0wr01dHFStjSFMvsBzFZClvDIrHLL5xbCOPaUOJ0=|493|1|7cBhJxVfQxWo+DypOISRpeWdQBhuQpAZtUbQHjBm8NQ=>

func (*Channel) PrivacyLevel

func (c *Channel) PrivacyLevel() PrivacyLevel

PrivacyLevel returns the Level of privacy set for this channel.

func (*Channel) ShareURL

func (c *Channel) ShareURL(
	host string, maxUses int, csprng io.Reader) (string, string, error)

ShareURL generates a URL that can be used to share this channel with others on the given host.

The RNG is only used for generating passwords for Private or Secret channels. It can be set to nil for Public channels. No password is returned for Public channels.

A URL comes in one of three forms based on the privacy Level set when generating the channel. Each privacy Level hides more information than the last with the lowest Level revealing everything and the highest Level revealing nothing. For any Level above the lowest, a password is returned, which will be required when decoding the URL.

The maxUses is the maximum number of times this URL can be used to join a channel. If it is set to 0, then it can be shared unlimited times. The max uses is set as a URL parameter using the key MaxUsesKey. Note that this number is also encoded in the secret data for private and secret URLs, so if the number is changed in the URL, is will be verified when calling DecodeShareURL. There is no enforcement for public URLs.

func (*Channel) Verify

func (c *Channel) Verify() bool

Verify checks that the channel ID is the same one generated by the channel primitives.

type PrivacyLevel

type PrivacyLevel uint8

PrivacyLevel describes the privacy Level of a Channel and dedicates how much channel information to reveal when sharing.

const (
	// Public channels expose all metadata when sharing (name, description,
	// privacy level, identity public keys)
	Public PrivacyLevel = iota

	// Private channels only expose their name and description when sharing.
	Private

	// Secret channels expose no information when sharing.
	Secret
)

func GetShareUrlType

func GetShareUrlType(url string) (PrivacyLevel, error)

GetShareUrlType determines the PrivacyLevel of the channel's URL.

func UnmarshalPrivacyLevel

func UnmarshalPrivacyLevel(s string) (PrivacyLevel, error)

UnmarshalPrivacyLevel unmarshalls the marshalled string into a PrivacyLevel.

func (PrivacyLevel) Marshal

func (pl PrivacyLevel) Marshal() string

Marshal marshals the PrivacyLevel into a string.

func (PrivacyLevel) String

func (pl PrivacyLevel) String() string

String returns a human-readable name for the PrivacyLevel. Used for debugging.

func (PrivacyLevel) Verify

func (pl PrivacyLevel) Verify() bool

Verify returns of the PrivacyLevel is valid.

Directories

Path Synopsis
Package escape includes helpers for escaping and unescaping strings.
Package escape includes helpers for escaping and unescaping strings.

Jump to

Keyboard shortcuts

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