4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-07-04 04:17:45 +00:00

Add dependencies/vendor (whatsapp)

This commit is contained in:
Wim
2022-01-31 00:27:37 +01:00
parent e7b193788a
commit e3cafeaf92
1074 changed files with 3091569 additions and 26075 deletions

View File

@ -0,0 +1,127 @@
// Package chain provides chain keys used in double ratchet sessions.
package chain
import (
"crypto/hmac"
"crypto/sha256"
"go.mau.fi/libsignal/kdf"
"go.mau.fi/libsignal/keys/message"
)
var messageKeySeed = []byte{0x01}
var chainKeySeed = []byte{0x02}
// NewKey returns a new chain key with the given kdf, key, and index
func NewKey(kdf kdf.HKDF, key []byte, index uint32) *Key {
chainKey := Key{
kdf: kdf,
key: key,
index: index,
}
return &chainKey
}
// NewKeyFromStruct will return a chain key built from the given structure.
func NewKeyFromStruct(structure *KeyStructure, kdf kdf.HKDF) *Key {
return NewKey(
kdf,
structure.Key,
structure.Index,
)
}
// NewStructFromKey will return a chain key structure for serialization.
func NewStructFromKey(key *Key) *KeyStructure {
return &KeyStructure{
Key: key.key,
Index: key.index,
}
}
// KeyStructure is a serializeable structure for chain keys.
type KeyStructure struct {
Key []byte
Index uint32
}
// Key is used for generating message keys. This key "ratchets" every time a
// message key is generated. Every time the chain key ratchets forward, its index
// increases by one.
type Key struct {
kdf kdf.HKDF
key []byte
index uint32 // Index's maximum size: 4,294,967,295
}
// Current returns the current ChainKey struct.
func (c *Key) Current() *Key {
return c
}
// Key returns the ChainKey's key material.
func (c *Key) Key() []byte {
return c.key
}
// SetKey will set the ChainKey's key material.
func (c *Key) SetKey(key []byte) {
c.key = key
}
// Index returns how many times the ChainKey has been "ratcheted" forward.
func (c *Key) Index() uint32 {
return c.index
}
// SetIndex sets how many times the ChainKey has been "ratcheted" forward.
func (c *Key) SetIndex(index uint32) {
c.index = index
}
// NextKey uses the key derivation function to generate a new ChainKey.
func (c *Key) NextKey() *Key {
nextKey := c.BaseMaterial(chainKeySeed)
return NewKey(c.kdf, nextKey, c.index+1)
}
// MessageKeys returns message keys, which includes the cipherkey, mac, iv, and index.
func (c *Key) MessageKeys() *message.Keys {
inputKeyMaterial := c.BaseMaterial(messageKeySeed)
keyMaterialBytes, _ := c.kdf(inputKeyMaterial, nil, []byte(message.KdfSalt), message.DerivedSecretsSize)
keyMaterial := newKeyMaterial(keyMaterialBytes)
// Use the key material returned from the key derivation function for our cipherkey, mac, and iv.
messageKeys := message.NewKeys(
keyMaterial.CipherKey, // Use the first 32 bytes of the key material for the CipherKey
keyMaterial.MacKey, // Use bytes 32-64 of the key material for the MacKey
keyMaterial.IV, // Use the last 16 bytes for the IV.
c.Index(), // Attach the chain key's index to the message keys.
)
return messageKeys
}
// BaseMaterial uses hmac to derive the base material used in the key derivation function for a new key.
func (c *Key) BaseMaterial(seed []byte) []byte {
mac := hmac.New(sha256.New, c.key[:])
mac.Write(seed)
return mac.Sum(nil)
}
// NewKeyMaterial takes an 80-byte slice derived from a key derivation function and splits
// it into the cipherkey, mac, and iv.
func newKeyMaterial(keyMaterialBytes []byte) *kdf.KeyMaterial {
cipherKey := keyMaterialBytes[:32] // Use the first 32 bytes of the key material for the CipherKey
macKey := keyMaterialBytes[32:64] // Use bytes 32-64 of the key material for the MacKey
iv := keyMaterialBytes[64:80] // Use the last 16 bytes for the IV.
keyMaterial := kdf.KeyMaterial{
CipherKey: cipherKey,
MacKey: macKey,
IV: iv,
}
return &keyMaterial
}

View File

@ -0,0 +1,47 @@
// Package identity provides identity keys used for verifying the identity
// of a signal user.
package identity
import (
"encoding/hex"
"go.mau.fi/libsignal/ecc"
)
// NewKey generates a new IdentityKey from an ECPublicKey
func NewKey(publicKey ecc.ECPublicKeyable) *Key {
identityKey := Key{
publicKey: publicKey,
}
return &identityKey
}
// NewKeyFromBytes generates a new IdentityKey from public key bytes
func NewKeyFromBytes(publicKey [32]byte, offset int) Key {
identityKey := Key{
publicKey: ecc.NewDjbECPublicKey(publicKey),
}
return identityKey
}
// Key is a structure for representing an identity key. This same structure can
// be used for verifying recipient's identity key or storing our own identity key.
type Key struct {
publicKey ecc.ECPublicKeyable
}
// Fingerprint gets the string fingerprint representation of the public key.
func (k *Key) Fingerprint() string {
return hex.EncodeToString(k.publicKey.Serialize())
}
// PublicKey returns the EC Public key of the identity key
func (k *Key) PublicKey() ecc.ECPublicKeyable {
return k.publicKey
}
// Serialize returns the serialized version of the key
func (k *Key) Serialize() []byte {
return k.publicKey.Serialize()
}

View File

@ -0,0 +1,39 @@
package identity
import (
"go.mau.fi/libsignal/ecc"
)
// NewKeyPair returns a new identity key with the given public and private keys.
func NewKeyPair(publicKey *Key, privateKey ecc.ECPrivateKeyable) *KeyPair {
keyPair := KeyPair{
publicKey: publicKey,
privateKey: privateKey,
}
return &keyPair
}
// NewKeyPairFromBytes returns a new identity key from the given serialized bytes.
//func NewKeyPairFromBytes(serialized []byte) KeyPair {
//}
// KeyPair is a holder for public and private identity key pair.
type KeyPair struct {
publicKey *Key
privateKey ecc.ECPrivateKeyable
}
// PublicKey returns the identity key's public key.
func (k *KeyPair) PublicKey() *Key {
return k.publicKey
}
// PrivateKey returns the identity key's private key.
func (k *KeyPair) PrivateKey() ecc.ECPrivateKeyable {
return k.privateKey
}
// Serialize returns a byte array that represents the keypair.
//func (k *KeyPair) Serialize() []byte {
//}

View File

@ -0,0 +1,91 @@
// Package message provides a structure for message keys, which are symmetric
// keys used for the encryption/decryption of Signal messages.
package message
// DerivedSecretsSize is the size of the derived secrets for message keys.
const DerivedSecretsSize = 80
// CipherKeyLength is the length of the actual cipher key used for messages.
const CipherKeyLength = 32
// MacKeyLength is the length of the message authentication code in bytes.
const MacKeyLength = 32
// IVLength is the length of the initialization vector in bytes.
const IVLength = 16
// KdfSalt is used as the Salt for message keys to derive secrets using a Key Derivation Function
const KdfSalt string = "WhisperMessageKeys"
// NewKeys returns a new message keys structure with the given cipherKey, mac, iv, and index.
func NewKeys(cipherKey, macKey, iv []byte, index uint32) *Keys {
messageKeys := Keys{
cipherKey: cipherKey,
macKey: macKey,
iv: iv,
index: index,
}
return &messageKeys
}
// NewKeysFromStruct will return a new message keys object from the
// given serializeable structure.
func NewKeysFromStruct(structure *KeysStructure) *Keys {
return NewKeys(
structure.CipherKey,
structure.MacKey,
structure.IV,
structure.Index,
)
}
// NewStructFromKeys returns a serializeable structure of message keys.
func NewStructFromKeys(keys *Keys) *KeysStructure {
return &KeysStructure{
CipherKey: keys.cipherKey,
MacKey: keys.macKey,
IV: keys.iv,
Index: keys.index,
}
}
// KeysStructure is a serializeable structure of message keys.
type KeysStructure struct {
CipherKey []byte
MacKey []byte
IV []byte
Index uint32
}
// Keys is a structure to hold all the keys for a single MessageKey, including the
// cipherKey, mac, iv, and index of the chain key. MessageKeys are used to
// encrypt individual messages.
type Keys struct {
cipherKey []byte
macKey []byte
iv []byte
index uint32
}
// CipherKey is the key used to produce ciphertext.
func (k *Keys) CipherKey() []byte {
return k.cipherKey
}
// MacKey returns the message's message authentication code.
func (k *Keys) MacKey() []byte {
return k.macKey
}
// Iv returns the message keys' initialization vector. The IV is a fixed-size input
// to a cryptographic primitive.
func (k *Keys) Iv() []byte {
return k.iv
}
// Index returns the number of times the chain key has been put through a key derivation
// function to generate this message key.
func (k *Keys) Index() uint32 {
return k.index
}

View File

@ -0,0 +1,86 @@
// Package prekey provides prekey bundle structures for calculating
// a new Signal session with a user asyncronously.
package prekey
import (
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/keys/identity"
"go.mau.fi/libsignal/util/optional"
)
// NewBundle returns a Bundle structure that contains a remote PreKey
// and collection of associated items.
func NewBundle(registrationID, deviceID uint32, preKeyID *optional.Uint32, signedPreKeyID uint32,
preKeyPublic, signedPreKeyPublic ecc.ECPublicKeyable, signedPreKeySig [64]byte,
identityKey *identity.Key) *Bundle {
bundle := Bundle{
registrationID: registrationID,
deviceID: deviceID,
preKeyID: preKeyID,
preKeyPublic: preKeyPublic,
signedPreKeyID: signedPreKeyID,
signedPreKeyPublic: signedPreKeyPublic,
signedPreKeySignature: signedPreKeySig,
identityKey: identityKey,
}
return &bundle
}
// Bundle is a structure that contains a remote PreKey and collection
// of associated items.
type Bundle struct {
registrationID uint32
deviceID uint32
preKeyID *optional.Uint32
preKeyPublic ecc.ECPublicKeyable
signedPreKeyID uint32
signedPreKeyPublic ecc.ECPublicKeyable
signedPreKeySignature [64]byte
identityKey *identity.Key
}
// DeviceID returns the device ID this PreKey belongs to.
func (b *Bundle) DeviceID() uint32 {
return b.deviceID
}
// PreKeyID returns the unique key ID for this PreKey.
func (b *Bundle) PreKeyID() *optional.Uint32 {
return b.preKeyID
}
// PreKey returns the public key for this PreKey.
func (b *Bundle) PreKey() ecc.ECPublicKeyable {
return b.preKeyPublic
}
// SignedPreKeyID returns the unique key ID for this
// signed PreKey.
func (b *Bundle) SignedPreKeyID() uint32 {
return b.signedPreKeyID
}
// SignedPreKey returns the signed PreKey for this
// PreKeyBundle.
func (b *Bundle) SignedPreKey() ecc.ECPublicKeyable {
return b.signedPreKeyPublic
}
// SignedPreKeySignature returns the signature over the
// signed PreKey.
func (b *Bundle) SignedPreKeySignature() [64]byte {
return b.signedPreKeySignature
}
// IdentityKey returns the Identity Key of this PreKey's owner.
func (b *Bundle) IdentityKey() *identity.Key {
return b.identityKey
}
// RegistrationID returns the registration ID associated with
// this PreKey.
func (b *Bundle) RegistrationID() uint32 {
return b.registrationID
}

View File

@ -0,0 +1,66 @@
// Package root provides root keys which are used to derive new chain and
// root keys in a ratcheting session.
package root
import (
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/kdf"
"go.mau.fi/libsignal/keys/chain"
"go.mau.fi/libsignal/keys/session"
)
// DerivedSecretsSize is the size of the derived secrets for root keys.
const DerivedSecretsSize = 64
// KdfInfo is used as the info for message keys to derive secrets using a Key Derivation Function
const KdfInfo string = "WhisperRatchet"
// NewKey returns a new RootKey given the key derivation function and bytes.
func NewKey(kdf kdf.HKDF, key []byte) *Key {
rootKey := Key{
kdf: kdf,
key: key,
}
return &rootKey
}
// Key is a structure for RootKeys, which are used to derive a new set of chain and root
// keys for every round trip of messages.
type Key struct {
kdf kdf.HKDF
key []byte
}
// Bytes returns the RootKey in bytes.
func (k *Key) Bytes() []byte {
return k.key
}
// CreateChain creates a new RootKey and ChainKey from the recipient's ratchet key and our private key.
func (k *Key) CreateChain(theirRatchetKey ecc.ECPublicKeyable, ourRatchetKey *ecc.ECKeyPair) (*session.KeyPair, error) {
theirPublicKey := theirRatchetKey.PublicKey()
ourPrivateKey := ourRatchetKey.PrivateKey().Serialize()
// Use our key derivation function to calculate a shared secret.
sharedSecret := kdf.CalculateSharedSecret(theirPublicKey, ourPrivateKey)
derivedSecretBytes, err := kdf.DeriveSecrets(sharedSecret[:], k.key, []byte(KdfInfo), DerivedSecretsSize)
if err != nil {
return nil, err
}
// Split the derived secret bytes in half, using one half for the root key and the second for the chain key.
derivedSecrets := session.NewDerivedSecrets(derivedSecretBytes)
// Create new root and chain key structures from the derived secrets.
rootKey := NewKey(k.kdf, derivedSecrets.RootKey())
chainKey := chain.NewKey(k.kdf, derivedSecrets.ChainKey(), 0)
// Create a session keypair with the generated root and chain keys.
keyPair := session.NewKeyPair(
rootKey,
chainKey,
)
return keyPair, nil
}

View File

@ -0,0 +1,29 @@
package session
// NewDerivedSecrets returns a new RootKey/ChainKey pair from 64 bytes of key material
// generated by the key derivation function.
func NewDerivedSecrets(keyMaterial []byte) *DerivedSecrets {
secrets := DerivedSecrets{
keyMaterial[:32],
keyMaterial[32:],
}
return &secrets
}
// DerivedSecrets is a structure for holding the derived secrets for the
// Root and Chain keys for a session.
type DerivedSecrets struct {
rootKey []byte
chainKey []byte
}
// RootKey returns the RootKey bytes.
func (d *DerivedSecrets) RootKey() []byte {
return d.rootKey
}
// ChainKey returns the ChainKey bytes.
func (d *DerivedSecrets) ChainKey() []byte {
return d.chainKey
}

View File

@ -0,0 +1,43 @@
// Package session provides a simple structure for session keys, which is
// a pair of root and chain keys for a session.
package session
import (
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/keys/chain"
"go.mau.fi/libsignal/keys/message"
)
// RootKeyable is an interface for all root key implementations that are part of
// a session keypair.
type RootKeyable interface {
Bytes() []byte
CreateChain(theirRatchetKey ecc.ECPublicKeyable, ourRatchetKey *ecc.ECKeyPair) (*KeyPair, error)
}
// ChainKeyable is an interface for all chain key implementations that are part of
// a session keypair.
type ChainKeyable interface {
Key() []byte
Index() uint32
NextKey() *chain.Key
MessageKeys() *message.Keys
Current() *chain.Key
}
// NewKeyPair returns a new session key pair that holds a root and chain key.
func NewKeyPair(rootKey RootKeyable, chainKey ChainKeyable) *KeyPair {
keyPair := KeyPair{
RootKey: rootKey,
ChainKey: chainKey,
}
return &keyPair
}
// KeyPair is a session key pair that holds a single root and chain key pair. These
// keys are ratcheted after every message sent and every message round trip.
type KeyPair struct {
RootKey RootKeyable
ChainKey ChainKeyable
}