Documentation ¶
Index ¶
- Constants
- Variables
- func DecodeSizedBroadcast(data []byte) ([]byte, error)
- func ExportPrivateKey(channelID *id.ID, privKey rsa.PrivateKey, encryptionPassword string, ...) ([]byte, error)
- func ExportPrivateKeyCustomParams(channelID *id.ID, privKey rsa.PrivateKey, encryptionPassword string, ...) ([]byte, error)
- func GetSizedBroadcastSize(data []byte) uint16
- func HashPubKey(pub rsa.PublicKey) []byte
- func HashSecret(secret []byte) []byte
- func HashURLPassword(password string) []byte
- func ImportPrivateKey(encryptionPassword string, data []byte) (*id.ID, rsa.PrivateKey, error)
- func MaxSizedBroadcastPayloadSize(outerPayloadSize int) int
- func NewChannelID(name, description string, level PrivacyLevel, created time.Time, ...) (*id.ID, error)
- func NewSizedBroadcast(outerPayloadSize int, payload []byte, rng io.Reader) ([]byte, error)
- func NewSymmetricKey(name, description string, level PrivacyLevel, creation time.Time, ...) ([]byte, error)
- func VerifyDescription(description string) error
- func VerifyName(name string) error
- type Channel
- func DecodeInviteURL(url string, password []byte) (*Channel, error)
- func DecodeShareURL(url, password string) (*Channel, error)
- func NewChannel(name, description string, level PrivacyLevel, packetPayloadLength int, ...) (*Channel, rsa.PrivateKey, error)
- func NewChannelFromPrettyPrint(p string) (*Channel, error)
- func NewChannelVariableKeyUnsafe(name, description string, level PrivacyLevel, created time.Time, ...) (*Channel, rsa.PrivateKey, error)
- func UnmarshalChannel(data []byte) (*Channel, error)
- func (c *Channel) DecryptRSAToPrivate(private rsa.PrivateKey, payload []byte, mac []byte, nonce format.Fingerprint) ([]byte, error)
- func (c *Channel) DecryptRSAToPublic(payload, mac []byte, nonce format.Fingerprint) (decrypted, innerCiphertext []byte, err error)
- func (c *Channel) DecryptRSAToPublicInner(innerCiphertext []byte) ([]byte, error)
- func (c *Channel) DecryptSymmetric(encryptedPayload, mac []byte, nonce format.Fingerprint) ([]byte, error)
- func (c *Channel) EncryptRSAToPrivate(payload []byte, pubkey rsa.PublicKey, outerPayloadSize int, rng csprng.Source) (doubleEncryptedPayload, mac []byte, nonce format.Fingerprint, err error)
- func (c *Channel) EncryptRSAToPublic(payload []byte, privKey rsa.PrivateKey, outerPayloadSize int, ...) (singleEncryptedPayload, doubleEncryptedPayload, mac []byte, ...)
- func (c *Channel) EncryptSymmetric(payload []byte, outerPayloadSize int, csprng csprng.Source) (encryptedPayload, mac []byte, nonce format.Fingerprint, err error)
- func (c *Channel) GetMaxSymmetricPayloadSize(outerPayloadSize int) int
- func (c *Channel) GetRSAToPrivateMessageLength() (size int, numSubPayloads int, subPayloadSize int)
- func (c *Channel) GetRSAToPublicMessageLength() (size int, numSubPayloads int, subPayloadSize int)
- func (c *Channel) IsPublicKey(publicKey rsa.PublicKey) bool
- func (c *Channel) Marshal() ([]byte, error)
- func (c *Channel) PrettyPrint() string
- func (c *Channel) PrivacyLevel() PrivacyLevel
- func (c *Channel) ShareURL(host string, maxUses int, csprng io.Reader) (string, string, error)
- func (c *Channel) Verify() bool
- type PrivacyLevel
Constants ¶
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 )
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 ¶
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.
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 ¶
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 ¶
GetSizedBroadcastSize returns the size of the sized broadcast, used for testing
func HashPubKey ¶
HashPubKey is used to compute the hash of the RSA Public Key
func HashSecret ¶
HashSecret secret is hashed first so that we can share all the inputs to the hkdf without giving out the secret.
func HashURLPassword ¶
HashURLPassword will hash the password given by Channel.ShareURL.
func ImportPrivateKey ¶
ImportPrivateKey returns the channel ID and private RSA key in the encrypted portable string.
func MaxSizedBroadcastPayloadSize ¶
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 ¶
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 ¶
VerifyDescription verifies that the description is a valid channel description.
func VerifyName ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
IsPublicKey returns true if the passed public key is the public key for the given channel
func (*Channel) PrettyPrint ¶
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 ¶
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.
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.