4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-06-27 15:49:23 +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,197 @@
// Package ratchet provides the methods necessary to establish a new double
// ratchet session.
package ratchet
import (
"encoding/base64"
"encoding/binary"
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/kdf"
"go.mau.fi/libsignal/keys/chain"
"go.mau.fi/libsignal/keys/root"
"go.mau.fi/libsignal/keys/session"
)
var b64 = base64.StdEncoding.EncodeToString
func genDiscontinuity() [32]byte {
var discontinuity [32]byte
for i := range discontinuity {
discontinuity[i] = 0xFF
}
return discontinuity
}
// CalculateSenderSession calculates the key agreement for a recipient. This
// should be used when we are trying to send a message to someone for the
// first time.
func CalculateSenderSession(parameters *SenderParameters) (*session.KeyPair, error) {
var secret [32]byte
var publicKey [32]byte
var privateKey [32]byte
masterSecret := []byte{} // Create a master shared secret that is 5 different 32-byte values
discontinuity := genDiscontinuity()
masterSecret = append(masterSecret, discontinuity[:]...)
// Calculate the agreement using their signed prekey and our identity key.
publicKey = parameters.TheirSignedPreKey().PublicKey()
privateKey = parameters.OurIdentityKey().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
// Calculate the agreement using their identity key and our base key.
publicKey = parameters.TheirIdentityKey().PublicKey().PublicKey()
privateKey = parameters.OurBaseKey().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
// Calculate the agreement using their signed prekey and our base key.
publicKey = parameters.TheirSignedPreKey().PublicKey()
privateKey = parameters.OurBaseKey().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
// If they have a one-time prekey, use it to calculate the shared secret with their
// one time key and our base key.
if parameters.TheirOneTimePreKey() != nil {
publicKey = parameters.TheirOneTimePreKey().PublicKey()
privateKey = parameters.OurBaseKey().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
}
// Derive the root and chain keys based on the master secret.
derivedKeysBytes, err := kdf.DeriveSecrets(masterSecret, nil, []byte("WhisperText"), root.DerivedSecretsSize)
if err != nil {
return nil, err
}
derivedKeys := session.NewDerivedSecrets(derivedKeysBytes)
chainKey := chain.NewKey(kdf.DeriveSecrets, derivedKeys.ChainKey(), 0)
rootKey := root.NewKey(kdf.DeriveSecrets, derivedKeys.RootKey())
// Add the root and chain keys to a structure that will hold both keys.
sessionKeys := session.NewKeyPair(rootKey, chainKey)
return sessionKeys, nil
}
// CalculateReceiverSession calculates the key agreement for a sender. This should
// be used when we are receiving a message from someone for the first time.
func CalculateReceiverSession(parameters *ReceiverParameters) (*session.KeyPair, error) {
var secret [32]byte
var publicKey [32]byte
var privateKey [32]byte
masterSecret := []byte{} // Create a master shared secret that is 5 different 32-byte values
discontinuity := genDiscontinuity()
masterSecret = append(masterSecret, discontinuity[:]...)
// Calculate the agreement using their identity key and our signed pre key.
publicKey = parameters.TheirIdentityKey().PublicKey().PublicKey()
privateKey = parameters.OurSignedPreKey().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
// Calculate the agreement using their base key and our identity key.
publicKey = parameters.TheirBaseKey().PublicKey()
privateKey = parameters.OurIdentityKeyPair().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
// Calculate the agreement using their base key and our signed prekey.
publicKey = parameters.TheirBaseKey().PublicKey()
privateKey = parameters.OurSignedPreKey().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
// If we had a one-time prekey, use it to calculate the shared secret with our
// one time key and their base key.
if parameters.OurOneTimePreKey() != nil {
publicKey = parameters.TheirBaseKey().PublicKey()
privateKey = parameters.OurOneTimePreKey().PrivateKey().Serialize()
secret = kdf.CalculateSharedSecret(
publicKey,
privateKey,
)
masterSecret = append(masterSecret, secret[:]...)
}
// Derive the root and chain keys based on the master secret.
derivedKeysBytes, err := kdf.DeriveSecrets(masterSecret, nil, []byte("WhisperText"), root.DerivedSecretsSize)
if err != nil {
return nil, err
}
derivedKeys := session.NewDerivedSecrets(derivedKeysBytes)
chainKey := chain.NewKey(kdf.DeriveSecrets, derivedKeys.ChainKey(), 0)
rootKey := root.NewKey(kdf.DeriveSecrets, derivedKeys.RootKey())
// Add the root and chain keys to a structure that will hold both keys.
sessionKeys := session.NewKeyPair(rootKey, chainKey)
return sessionKeys, nil
}
// CalculateSymmetricSession calculates the key agreement between two users. This
// works by both clients exchanging KeyExchange messages to first establish a session.
// This is useful for establishing a session if both users are online.
func CalculateSymmetricSession(parameters *SymmetricParameters) (*session.KeyPair, error) {
// Compare the base public keys so we can deterministically know whether we should
// be setting up a sender or receiver session. If our key converted to an integer is
// less than the other user's, act as a sender.
if isSender(parameters.OurBaseKey.PublicKey(), parameters.TheirBaseKey) {
senderParameters := &SenderParameters{
ourBaseKey: parameters.OurBaseKey,
ourIdentityKeyPair: parameters.OurIdentityKeyPair,
theirRatchetKey: parameters.TheirRatchetKey,
theirIdentityKey: parameters.TheirIdentityKey,
theirSignedPreKey: parameters.TheirBaseKey,
}
return CalculateSenderSession(senderParameters)
}
// If our base public key was larger than the other user's, act as a receiver.
receiverParameters := &ReceiverParameters{
ourIdentityKeyPair: parameters.OurIdentityKeyPair,
ourRatchetKey: parameters.OurRatchetKey,
ourSignedPreKey: parameters.OurBaseKey,
theirBaseKey: parameters.TheirBaseKey,
theirIdentityKey: parameters.TheirIdentityKey,
}
return CalculateReceiverSession(receiverParameters)
}
// isSender is a private method for determining if a symmetric session should
// be calculated as the sender or receiver. It does so by converting the given
// keys into integers and comparing the size of those integers.
func isSender(ourKey, theirKey ecc.ECPublicKeyable) bool {
ourKeyInt := binary.BigEndian.Uint32(ourKey.Serialize())
theirKeyInt := binary.BigEndian.Uint32(theirKey.Serialize())
return ourKeyInt < theirKeyInt
}

View File

@ -0,0 +1,106 @@
package ratchet
import (
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/keys/identity"
)
// NewReceiverParameters creates a structure with all the keys needed to construct
// a new session when we are receiving a message from a user for the first time.
func NewReceiverParameters(ourIdentityKey *identity.KeyPair, ourSignedPreKey *ecc.ECKeyPair,
ourOneTimePreKey *ecc.ECKeyPair, ourRatchetKey *ecc.ECKeyPair,
theirBaseKey ecc.ECPublicKeyable, theirIdentityKey *identity.Key) *ReceiverParameters {
receiverParams := ReceiverParameters{
ourIdentityKeyPair: ourIdentityKey,
ourSignedPreKey: ourSignedPreKey,
ourOneTimePreKey: ourOneTimePreKey,
ourRatchetKey: ourRatchetKey,
theirBaseKey: theirBaseKey,
theirIdentityKey: theirIdentityKey,
}
return &receiverParams
}
// NewEmptyReceiverParameters creates an empty structure with the receiver parameters
// needed to create a session. You should use the `set` functions to set all the
// necessary keys needed to build a session.
func NewEmptyReceiverParameters() *ReceiverParameters {
receiverParams := ReceiverParameters{}
return &receiverParams
}
// ReceiverParameters describes the session parameters if we are receiving
// a message from someone for the first time. These parameters are used as
// the basis for deriving a shared secret with the sender.
type ReceiverParameters struct {
ourIdentityKeyPair *identity.KeyPair
ourSignedPreKey *ecc.ECKeyPair
ourOneTimePreKey *ecc.ECKeyPair
ourRatchetKey *ecc.ECKeyPair
theirBaseKey ecc.ECPublicKeyable
theirIdentityKey *identity.Key
}
// OurIdentityKeyPair returns the identity key of the receiver.
func (r *ReceiverParameters) OurIdentityKeyPair() *identity.KeyPair {
return r.ourIdentityKeyPair
}
// OurSignedPreKey returns the signed prekey of the receiver.
func (r *ReceiverParameters) OurSignedPreKey() *ecc.ECKeyPair {
return r.ourSignedPreKey
}
// OurOneTimePreKey returns the one time prekey of the receiver.
func (r *ReceiverParameters) OurOneTimePreKey() *ecc.ECKeyPair {
return r.ourOneTimePreKey
}
// OurRatchetKey returns the ratchet key of the receiver.
func (r *ReceiverParameters) OurRatchetKey() *ecc.ECKeyPair {
return r.ourRatchetKey
}
// TheirBaseKey returns the base key of the sender.
func (r *ReceiverParameters) TheirBaseKey() ecc.ECPublicKeyable {
return r.theirBaseKey
}
// TheirIdentityKey returns the identity key of the sender.
func (r *ReceiverParameters) TheirIdentityKey() *identity.Key {
return r.theirIdentityKey
}
// SetOurIdentityKeyPair sets the identity key of the receiver.
func (r *ReceiverParameters) SetOurIdentityKeyPair(ourIdentityKey *identity.KeyPair) {
r.ourIdentityKeyPair = ourIdentityKey
}
// SetOurSignedPreKey sets the signed prekey of the receiver.
func (r *ReceiverParameters) SetOurSignedPreKey(ourSignedPreKey *ecc.ECKeyPair) {
r.ourSignedPreKey = ourSignedPreKey
}
// SetOurOneTimePreKey sets the one time prekey of the receiver.
func (r *ReceiverParameters) SetOurOneTimePreKey(ourOneTimePreKey *ecc.ECKeyPair) {
r.ourOneTimePreKey = ourOneTimePreKey
}
// SetOurRatchetKey sets the ratchet key of the receiver.
func (r *ReceiverParameters) SetOurRatchetKey(ourRatchetKey *ecc.ECKeyPair) {
r.ourRatchetKey = ourRatchetKey
}
// SetTheirBaseKey sets the base key of the sender.
func (r *ReceiverParameters) SetTheirBaseKey(theirBaseKey ecc.ECPublicKeyable) {
r.theirBaseKey = theirBaseKey
}
// SetTheirIdentityKey sets the identity key of the sender.
func (r *ReceiverParameters) SetTheirIdentityKey(theirIdentityKey *identity.Key) {
r.theirIdentityKey = theirIdentityKey
}

View File

@ -0,0 +1,106 @@
package ratchet
import (
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/keys/identity"
)
// NewSenderParameters creates a structure with all the keys needed to construct
// a new session when we are sending a message to a recipient for the first time.
func NewSenderParameters(ourIdentityKey *identity.KeyPair, ourBaseKey *ecc.ECKeyPair,
theirIdentityKey *identity.Key, theirSignedPreKey ecc.ECPublicKeyable,
theirRatchetKey ecc.ECPublicKeyable, theirOneTimePreKey ecc.ECPublicKeyable) *SenderParameters {
senderParams := SenderParameters{
ourIdentityKeyPair: ourIdentityKey,
ourBaseKey: ourBaseKey,
theirIdentityKey: theirIdentityKey,
theirSignedPreKey: theirSignedPreKey,
theirOneTimePreKey: theirOneTimePreKey,
theirRatchetKey: theirRatchetKey,
}
return &senderParams
}
// NewEmptySenderParameters creates an empty structure with the sender parameters
// needed to create a session. You should use the `set` functions to set all the
// necessary keys needed to build a session.
func NewEmptySenderParameters() *SenderParameters {
senderParams := SenderParameters{}
return &senderParams
}
// SenderParameters describes the session parameters if we are sending the
// recipient a message for the first time. These parameters are used as the
// basis for deriving a shared secret with a recipient.
type SenderParameters struct {
ourIdentityKeyPair *identity.KeyPair
ourBaseKey *ecc.ECKeyPair
theirIdentityKey *identity.Key
theirSignedPreKey ecc.ECPublicKeyable
theirOneTimePreKey ecc.ECPublicKeyable
theirRatchetKey ecc.ECPublicKeyable
}
// OurIdentityKey returns the identity key pair of the sender.
func (s *SenderParameters) OurIdentityKey() *identity.KeyPair {
return s.ourIdentityKeyPair
}
// OurBaseKey returns the base ECC key pair of the sender.
func (s *SenderParameters) OurBaseKey() *ecc.ECKeyPair {
return s.ourBaseKey
}
// TheirIdentityKey returns the identity public key of the receiver.
func (s *SenderParameters) TheirIdentityKey() *identity.Key {
return s.theirIdentityKey
}
// TheirSignedPreKey returns the signed pre key of the receiver.
func (s *SenderParameters) TheirSignedPreKey() ecc.ECPublicKeyable {
return s.theirSignedPreKey
}
// TheirOneTimePreKey returns the receiver's one time prekey.
func (s *SenderParameters) TheirOneTimePreKey() ecc.ECPublicKeyable {
return s.theirOneTimePreKey
}
// TheirRatchetKey returns the receiver's ratchet key.
func (s *SenderParameters) TheirRatchetKey() ecc.ECPublicKeyable {
return s.theirRatchetKey
}
// SetOurIdentityKey sets the identity key pair of the sender.
func (s *SenderParameters) SetOurIdentityKey(ourIdentityKey *identity.KeyPair) {
s.ourIdentityKeyPair = ourIdentityKey
}
// SetOurBaseKey sets the base ECC key pair of the sender.
func (s *SenderParameters) SetOurBaseKey(ourBaseKey *ecc.ECKeyPair) {
s.ourBaseKey = ourBaseKey
}
// SetTheirIdentityKey sets the identity public key of the receiver.
func (s *SenderParameters) SetTheirIdentityKey(theirIdentityKey *identity.Key) {
s.theirIdentityKey = theirIdentityKey
}
// SetTheirSignedPreKey sets the signed pre key of the receiver.
func (s *SenderParameters) SetTheirSignedPreKey(theirSignedPreKey ecc.ECPublicKeyable) {
s.theirSignedPreKey = theirSignedPreKey
}
// SetTheirOneTimePreKey sets the receiver's one time prekey.
func (s *SenderParameters) SetTheirOneTimePreKey(theirOneTimePreKey ecc.ECPublicKeyable) {
s.theirOneTimePreKey = theirOneTimePreKey
}
// SetTheirRatchetKey sets the receiver's ratchet key.
func (s *SenderParameters) SetTheirRatchetKey(theirRatchetKey ecc.ECPublicKeyable) {
s.theirRatchetKey = theirRatchetKey
}

View File

@ -0,0 +1,18 @@
package ratchet
import (
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/keys/identity"
)
// SymmetricParameters describes the session parameters for sessions where
// both users are online, which doesn't use prekeys for setup.
type SymmetricParameters struct {
OurBaseKey *ecc.ECKeyPair
OurRatchetKey *ecc.ECKeyPair
OurIdentityKeyPair *identity.KeyPair
TheirBaseKey ecc.ECPublicKeyable
TheirRatchetKey ecc.ECPublicKeyable
TheirIdentityKey *identity.Key
}