mirror of
https://mau.dev/mautrix/go.git
synced 2026-03-14 14:25:53 +01:00
goolm: use constants for pickle lengths when possible
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
parent
fbea2a067c
commit
bc1f09086f
16 changed files with 119 additions and 192 deletions
|
|
@ -488,14 +488,14 @@ func (a *Account) PickleLibOlm(target []byte) (int, error) {
|
|||
|
||||
// PickleLen returns the number of bytes the pickled Account will have.
|
||||
func (a *Account) PickleLen() int {
|
||||
length := libolmpickle.PickleUInt32Len(accountPickleVersionLibOLM)
|
||||
length += a.IdKeys.Ed25519.PickleLen()
|
||||
length += a.IdKeys.Curve25519.PickleLen()
|
||||
length += libolmpickle.PickleUInt32Len(uint32(len(a.OTKeys)))
|
||||
length += (len(a.OTKeys) * (&crypto.OneTimeKey{}).PickleLen())
|
||||
length += libolmpickle.PickleUInt8Len(a.NumFallbackKeys)
|
||||
length += (int(a.NumFallbackKeys) * (&crypto.OneTimeKey{}).PickleLen())
|
||||
length += libolmpickle.PickleUInt32Len(a.NextOneTimeKeyID)
|
||||
length := libolmpickle.PickleUInt32Length
|
||||
length += crypto.Ed25519KeyPairPickleLength // IdKeys.Ed25519
|
||||
length += crypto.Curve25519KeyPairPickleLength // IdKeys.Curve25519
|
||||
length += libolmpickle.PickleUInt32Length
|
||||
length += (len(a.OTKeys) * crypto.OneTimeKeyPickleLength)
|
||||
length += libolmpickle.PickleUInt8Length
|
||||
length += (int(a.NumFallbackKeys) * crypto.OneTimeKeyPickleLength)
|
||||
length += libolmpickle.PickleUInt32Length
|
||||
return length
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
const (
|
||||
Curve25519KeyLength = curve25519.ScalarSize //The length of the private key.
|
||||
curve25519PubKeyLength = 32
|
||||
Curve25519PubKeyLength = 32
|
||||
)
|
||||
|
||||
// Curve25519GenerateKey creates a new curve25519 key pair.
|
||||
|
|
@ -51,6 +51,9 @@ type Curve25519KeyPair struct {
|
|||
PublicKey Curve25519PublicKey `json:"public,omitempty"`
|
||||
}
|
||||
|
||||
const Curve25519KeyPairPickleLength = Curve25519PubKeyLength + // Public Key
|
||||
Curve25519KeyLength // Private Key
|
||||
|
||||
// B64Encoded returns a base64 encoded string of the public key.
|
||||
func (c Curve25519KeyPair) B64Encoded() id.Curve25519 {
|
||||
return c.PublicKey.B64Encoded()
|
||||
|
|
@ -61,10 +64,11 @@ func (c Curve25519KeyPair) SharedSecret(pubKey Curve25519PublicKey) ([]byte, err
|
|||
return c.PrivateKey.SharedSecret(pubKey)
|
||||
}
|
||||
|
||||
// PickleLibOlm encodes the key pair into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// PickleLibOlm encodes the key pair into target. The target has to have a size
|
||||
// of at least [Curve25519KeyPairPickleLength] and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (c Curve25519KeyPair) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < c.PickleLen() {
|
||||
if len(target) < Curve25519KeyPairPickleLength {
|
||||
return 0, fmt.Errorf("pickle curve25519 key pair: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written, err := c.PublicKey.PickleLibOlm(target)
|
||||
|
|
@ -95,18 +99,6 @@ func (c *Curve25519KeyPair) UnpickleLibOlm(value []byte) (int, error) {
|
|||
return read + readPriv, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled key pair will have.
|
||||
func (c Curve25519KeyPair) PickleLen() int {
|
||||
lenPublic := c.PublicKey.PickleLen()
|
||||
var lenPrivate int
|
||||
if len(c.PrivateKey) != Curve25519KeyLength {
|
||||
lenPrivate = libolmpickle.PickleBytesLen(make([]byte, Curve25519KeyLength))
|
||||
} else {
|
||||
lenPrivate = libolmpickle.PickleBytesLen(c.PrivateKey)
|
||||
}
|
||||
return lenPublic + lenPrivate
|
||||
}
|
||||
|
||||
// Curve25519PrivateKey represents the private key for curve25519 usage
|
||||
type Curve25519PrivateKey []byte
|
||||
|
||||
|
|
@ -141,29 +133,21 @@ func (c Curve25519PublicKey) B64Encoded() id.Curve25519 {
|
|||
// PickleLibOlm encodes the public key into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (c Curve25519PublicKey) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < c.PickleLen() {
|
||||
if len(target) < Curve25519PubKeyLength {
|
||||
return 0, fmt.Errorf("pickle curve25519 public key: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
if len(c) != curve25519PubKeyLength {
|
||||
return libolmpickle.PickleBytes(make([]byte, curve25519PubKeyLength), target), nil
|
||||
if len(c) != Curve25519PubKeyLength {
|
||||
return libolmpickle.PickleBytes(make([]byte, Curve25519PubKeyLength), target), nil
|
||||
}
|
||||
return libolmpickle.PickleBytes(c, target), nil
|
||||
}
|
||||
|
||||
// UnpickleLibOlm decodes the unencryted value and populates the public key accordingly. It returns the number of bytes read.
|
||||
func (c *Curve25519PublicKey) UnpickleLibOlm(value []byte) (int, error) {
|
||||
unpickled, readBytes, err := libolmpickle.UnpickleBytes(value, curve25519PubKeyLength)
|
||||
unpickled, readBytes, err := libolmpickle.UnpickleBytes(value, Curve25519PubKeyLength)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
*c = unpickled
|
||||
return readBytes, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled public key will have.
|
||||
func (c Curve25519PublicKey) PickleLen() int {
|
||||
if len(c) != curve25519PubKeyLength {
|
||||
return libolmpickle.PickleBytesLen(make([]byte, curve25519PubKeyLength))
|
||||
}
|
||||
return libolmpickle.PickleBytesLen(c)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func TestCurve25519Pickle(t *testing.T) {
|
|||
//create keypair
|
||||
keyPair, err := crypto.Curve25519GenerateKey()
|
||||
assert.NoError(t, err)
|
||||
target := make([]byte, keyPair.PickleLen())
|
||||
target := make([]byte, crypto.Curve25519KeyPairPickleLength)
|
||||
writtenBytes, err := keyPair.PickleLibOlm(target)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, target, writtenBytes)
|
||||
|
|
@ -92,7 +92,7 @@ func TestCurve25519PicklePubKeyOnly(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
//Remove privateKey
|
||||
keyPair.PrivateKey = nil
|
||||
target := make([]byte, keyPair.PickleLen())
|
||||
target := make([]byte, crypto.Curve25519KeyPairPickleLength)
|
||||
writtenBytes, err := keyPair.PickleLibOlm(target)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, target, writtenBytes)
|
||||
|
|
@ -109,7 +109,7 @@ func TestCurve25519PicklePrivKeyOnly(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
//Remove public
|
||||
keyPair.PublicKey = nil
|
||||
target := make([]byte, keyPair.PickleLen())
|
||||
target := make([]byte, crypto.Curve25519KeyPairPickleLength)
|
||||
writtenBytes, err := keyPair.PickleLibOlm(target)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, target, writtenBytes)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ type Ed25519KeyPair struct {
|
|||
PublicKey Ed25519PublicKey `json:"public,omitempty"`
|
||||
}
|
||||
|
||||
const Ed25519KeyPairPickleLength = ed25519.PublicKeySize + // PublicKey
|
||||
ed25519.PrivateKeySize // Private Key
|
||||
|
||||
// B64Encoded returns a base64 encoded string of the public key.
|
||||
func (c Ed25519KeyPair) B64Encoded() id.Ed25519 {
|
||||
return id.Ed25519(base64.RawStdEncoding.EncodeToString(c.PublicKey))
|
||||
|
|
@ -61,10 +64,11 @@ func (c Ed25519KeyPair) Verify(message, givenSignature []byte) bool {
|
|||
return c.PublicKey.Verify(message, givenSignature)
|
||||
}
|
||||
|
||||
// PickleLibOlm encodes the key pair into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
// PickleLibOlm encodes the key pair into target. target has to have a size of
|
||||
// at least [Ed25519KeyPairPickleLength] and is written to from index 0. It
|
||||
// returns the number of bytes written.
|
||||
func (c Ed25519KeyPair) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < c.PickleLen() {
|
||||
if len(target) < Ed25519KeyPairPickleLength {
|
||||
return 0, fmt.Errorf("pickle ed25519 key pair: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written, err := c.PublicKey.PickleLibOlm(target)
|
||||
|
|
@ -96,18 +100,6 @@ func (c *Ed25519KeyPair) UnpickleLibOlm(value []byte) (int, error) {
|
|||
return read + readPriv, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled key pair will have.
|
||||
func (c Ed25519KeyPair) PickleLen() int {
|
||||
lenPublic := c.PublicKey.PickleLen()
|
||||
var lenPrivate int
|
||||
if len(c.PrivateKey) != ed25519.PrivateKeySize {
|
||||
lenPrivate = libolmpickle.PickleBytesLen(make([]byte, ed25519.PrivateKeySize))
|
||||
} else {
|
||||
lenPrivate = libolmpickle.PickleBytesLen(c.PrivateKey)
|
||||
}
|
||||
return lenPublic + lenPrivate
|
||||
}
|
||||
|
||||
// Curve25519PrivateKey represents the private key for ed25519 usage. This is just a wrapper.
|
||||
type Ed25519PrivateKey ed25519.PrivateKey
|
||||
|
||||
|
|
@ -149,10 +141,11 @@ func (c Ed25519PublicKey) Verify(message, givenSignature []byte) bool {
|
|||
return ed25519.Verify(ed25519.PublicKey(c), message, givenSignature)
|
||||
}
|
||||
|
||||
// PickleLibOlm encodes the public key into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
// PickleLibOlm encodes the public key into target. target has to have a size
|
||||
// of at least [ed25519.PublicKeySize] and is written to from index 0. It
|
||||
// returns the number of bytes written.
|
||||
func (c Ed25519PublicKey) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < c.PickleLen() {
|
||||
if len(target) < ed25519.PublicKeySize {
|
||||
return 0, fmt.Errorf("pickle ed25519 public key: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
if len(c) != ed25519.PublicKeySize {
|
||||
|
|
@ -170,11 +163,3 @@ func (c *Ed25519PublicKey) UnpickleLibOlm(value []byte) (int, error) {
|
|||
*c = unpickled
|
||||
return readBytes, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled public key will have.
|
||||
func (c Ed25519PublicKey) PickleLen() int {
|
||||
if len(c) != ed25519.PublicKeySize {
|
||||
return libolmpickle.PickleBytesLen(make([]byte, ed25519.PublicKeySize))
|
||||
}
|
||||
return libolmpickle.PickleBytesLen(c)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func TestEd25519Pickle(t *testing.T) {
|
|||
//create keypair
|
||||
keyPair, err := crypto.Ed25519GenerateKey()
|
||||
assert.NoError(t, err)
|
||||
target := make([]byte, keyPair.PickleLen())
|
||||
target := make([]byte, crypto.Ed25519KeyPairPickleLength)
|
||||
writtenBytes, err := keyPair.PickleLibOlm(target)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, target, writtenBytes)
|
||||
|
|
@ -56,7 +56,7 @@ func TestEd25519PicklePubKeyOnly(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
//Remove privateKey
|
||||
keyPair.PrivateKey = nil
|
||||
target := make([]byte, keyPair.PickleLen())
|
||||
target := make([]byte, crypto.Ed25519KeyPairPickleLength)
|
||||
writtenBytes, err := keyPair.PickleLibOlm(target)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, target, writtenBytes)
|
||||
|
|
@ -74,7 +74,7 @@ func TestEd25519PicklePrivKeyOnly(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
//Remove public
|
||||
keyPair.PublicKey = nil
|
||||
target := make([]byte, keyPair.PickleLen())
|
||||
target := make([]byte, crypto.Ed25519KeyPairPickleLength)
|
||||
writtenBytes, err := keyPair.PickleLibOlm(target)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, target, writtenBytes)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ type OneTimeKey struct {
|
|||
Key Curve25519KeyPair `json:"key,omitempty"`
|
||||
}
|
||||
|
||||
const OneTimeKeyPickleLength = libolmpickle.PickleUInt32Length + // ID
|
||||
libolmpickle.PickleBoolLength + // Published
|
||||
Curve25519KeyPairPickleLength // Key
|
||||
|
||||
// Equal compares the one time key to the given one.
|
||||
func (otk OneTimeKey) Equal(s OneTimeKey) bool {
|
||||
if otk.ID != s.ID {
|
||||
|
|
@ -37,7 +41,7 @@ func (otk OneTimeKey) Equal(s OneTimeKey) bool {
|
|||
// PickleLibOlm encodes the key pair into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (c OneTimeKey) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < c.PickleLen() {
|
||||
if len(target) < OneTimeKeyPickleLength {
|
||||
return 0, fmt.Errorf("pickle one time key: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written := libolmpickle.PickleUInt32(uint32(c.ID), target)
|
||||
|
|
@ -73,15 +77,6 @@ func (c *OneTimeKey) UnpickleLibOlm(value []byte) (int, error) {
|
|||
return totalReadBytes, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled OneTimeKey will have.
|
||||
func (c OneTimeKey) PickleLen() int {
|
||||
length := 0
|
||||
length += libolmpickle.PickleUInt32Len(c.ID)
|
||||
length += libolmpickle.PickleBoolLen(c.Published)
|
||||
length += c.Key.PickleLen()
|
||||
return length
|
||||
}
|
||||
|
||||
// KeyIDEncoded returns the base64 encoded id.
|
||||
func (c OneTimeKey) KeyIDEncoded() string {
|
||||
resSlice := make([]byte, 4)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,16 @@ import (
|
|||
"encoding/binary"
|
||||
)
|
||||
|
||||
const (
|
||||
PickleBoolLength = 1
|
||||
PickleUInt8Length = 1
|
||||
PickleUInt32Length = 4
|
||||
)
|
||||
|
||||
func PickleUInt8(value uint8, target []byte) int {
|
||||
target[0] = value
|
||||
return 1
|
||||
}
|
||||
func PickleUInt8Len(value uint8) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func PickleBool(value bool, target []byte) int {
|
||||
if value {
|
||||
|
|
@ -20,9 +23,6 @@ func PickleBool(value bool, target []byte) int {
|
|||
}
|
||||
return 1
|
||||
}
|
||||
func PickleBoolLen(value bool) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func PickleBytes(value, target []byte) int {
|
||||
return copy(target, value)
|
||||
|
|
@ -36,6 +36,3 @@ func PickleUInt32(value uint32, target []byte) int {
|
|||
binary.BigEndian.PutUint32(res, value)
|
||||
return copy(target, res)
|
||||
}
|
||||
func PickleUInt32Len(value uint32) int {
|
||||
return 4
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ func TestPickleUInt32(t *testing.T) {
|
|||
for curIndex := range values {
|
||||
response := make([]byte, 4)
|
||||
resPLen := libolmpickle.PickleUInt32(values[curIndex], response)
|
||||
assert.Equal(t, libolmpickle.PickleUInt32Len(values[curIndex]), resPLen)
|
||||
assert.Equal(t, libolmpickle.PickleUInt32Length, resPLen)
|
||||
assert.Equal(t, expected[curIndex], response)
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ func TestPickleBool(t *testing.T) {
|
|||
for curIndex := range values {
|
||||
response := make([]byte, 1)
|
||||
resPLen := libolmpickle.PickleBool(values[curIndex], response)
|
||||
assert.Equal(t, libolmpickle.PickleBoolLen(values[curIndex]), resPLen)
|
||||
assert.Equal(t, libolmpickle.PickleBoolLength, resPLen)
|
||||
assert.Equal(t, expected[curIndex], response)
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ func TestPickleUInt8(t *testing.T) {
|
|||
for curIndex := range values {
|
||||
response := make([]byte, 1)
|
||||
resPLen := libolmpickle.PickleUInt8(values[curIndex], response)
|
||||
assert.Equal(t, libolmpickle.PickleUInt8Len(values[curIndex]), resPLen)
|
||||
assert.Equal(t, libolmpickle.PickleUInt8Length, resPLen)
|
||||
assert.Equal(t, expected[curIndex], response)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ const (
|
|||
protocolVersion = 3
|
||||
RatchetParts = 4 // number of ratchet parts
|
||||
RatchetPartLength = 256 / 8 // length of each ratchet part in bytes
|
||||
|
||||
RatchetPickleLength = (RatchetParts * RatchetPartLength) + //Data
|
||||
libolmpickle.PickleUInt32Length // Counter
|
||||
)
|
||||
|
||||
var RatchetCipher = cipher.NewAESSHA256([]byte("MEGOLM_KEYS"))
|
||||
|
|
@ -219,17 +222,10 @@ func (r *Ratchet) UnpickleLibOlm(unpickled []byte) (int, error) {
|
|||
// PickleLibOlm encodes the ratchet into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (r Ratchet) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < r.PickleLen() {
|
||||
if len(target) < RatchetPickleLength {
|
||||
return 0, fmt.Errorf("pickle account: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written := libolmpickle.PickleBytes(r.Data[:], target)
|
||||
written += libolmpickle.PickleUInt32(r.Counter, target[written:])
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled ratchet will have.
|
||||
func (r Ratchet) PickleLen() int {
|
||||
length := libolmpickle.PickleBytesLen(r.Data[:])
|
||||
length += libolmpickle.PickleUInt32Len(r.Counter)
|
||||
return length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ import (
|
|||
const (
|
||||
decryptionPickleVersionJSON uint8 = 1
|
||||
decryptionPickleVersionLibOlm uint32 = 1
|
||||
|
||||
DecryptionPickleLength = libolmpickle.PickleUInt32Length + // Version
|
||||
crypto.Curve25519KeyPairPickleLength // KeyPair
|
||||
)
|
||||
|
||||
// Decryption is used to decrypt pk messages
|
||||
|
|
@ -124,7 +127,7 @@ func (a *Decryption) UnpickleLibOlm(value []byte) (int, error) {
|
|||
|
||||
// Pickle returns a base64 encoded and with key encrypted pickled Decryption using PickleLibOlm().
|
||||
func (a Decryption) Pickle(key []byte) ([]byte, error) {
|
||||
pickeledBytes := make([]byte, a.PickleLen())
|
||||
pickeledBytes := make([]byte, DecryptionPickleLength)
|
||||
written, err := a.PickleLibOlm(pickeledBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -135,10 +138,11 @@ func (a Decryption) Pickle(key []byte) ([]byte, error) {
|
|||
return cipher.Pickle(key, pickeledBytes)
|
||||
}
|
||||
|
||||
// PickleLibOlm encodes the Decryption into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
// PickleLibOlm encodes the Decryption into target. target has to have a size
|
||||
// of at least [DecryptionPickleLength] and is written to from index 0. It
|
||||
// returns the number of bytes written.
|
||||
func (a Decryption) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < a.PickleLen() {
|
||||
if len(target) < DecryptionPickleLength {
|
||||
return 0, fmt.Errorf("pickle Decryption: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written := libolmpickle.PickleUInt32(decryptionPickleVersionLibOlm, target)
|
||||
|
|
@ -149,10 +153,3 @@ func (a Decryption) PickleLibOlm(target []byte) (int, error) {
|
|||
written += writtenKey
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled Decryption will have.
|
||||
func (a Decryption) PickleLen() int {
|
||||
length := libolmpickle.PickleUInt32Len(decryptionPickleVersionLibOlm)
|
||||
length += a.KeyPair.PickleLen()
|
||||
return length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ type chainKey struct {
|
|||
Key crypto.Curve25519PublicKey `json:"key"`
|
||||
}
|
||||
|
||||
const chainKeyPickleLength = crypto.Curve25519PubKeyLength + // Key
|
||||
libolmpickle.PickleUInt32Length // Index
|
||||
|
||||
// advance advances the chain
|
||||
func (c *chainKey) advance() {
|
||||
c.Key = crypto.HMACSHA256(c.Key, []byte{chainKeySeed})
|
||||
|
|
@ -44,7 +47,7 @@ func (r *chainKey) UnpickleLibOlm(value []byte) (int, error) {
|
|||
// PickleLibOlm encodes the chain key into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (r chainKey) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < r.PickleLen() {
|
||||
if len(target) < chainKeyPickleLength {
|
||||
return 0, fmt.Errorf("pickle chain key: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written, err := r.Key.PickleLibOlm(target)
|
||||
|
|
@ -55,13 +58,6 @@ func (r chainKey) PickleLibOlm(target []byte) (int, error) {
|
|||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled chain key will have.
|
||||
func (r chainKey) PickleLen() int {
|
||||
length := r.Key.PickleLen()
|
||||
length += libolmpickle.PickleUInt32Len(r.Index)
|
||||
return length
|
||||
}
|
||||
|
||||
// senderChain is a chain for sending messages
|
||||
type senderChain struct {
|
||||
RKey crypto.Curve25519KeyPair `json:"ratchet_key"`
|
||||
|
|
@ -69,6 +65,9 @@ type senderChain struct {
|
|||
IsSet bool `json:"set"`
|
||||
}
|
||||
|
||||
const senderChainPickleLength = chainKeyPickleLength + // RKey
|
||||
chainKeyPickleLength // CKey
|
||||
|
||||
// newSenderChain returns a sender chain initialized with chainKey and ratchet key pair.
|
||||
func newSenderChain(key crypto.Curve25519PublicKey, ratchet crypto.Curve25519KeyPair) *senderChain {
|
||||
return &senderChain{
|
||||
|
|
@ -115,7 +114,7 @@ func (r *senderChain) UnpickleLibOlm(value []byte) (int, error) {
|
|||
// PickleLibOlm encodes the chain into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (r senderChain) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < r.PickleLen() {
|
||||
if len(target) < senderChainPickleLength {
|
||||
return 0, fmt.Errorf("pickle sender chain: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written, err := r.RKey.PickleLibOlm(target)
|
||||
|
|
@ -130,19 +129,15 @@ func (r senderChain) PickleLibOlm(target []byte) (int, error) {
|
|||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled chain will have.
|
||||
func (r senderChain) PickleLen() int {
|
||||
length := r.RKey.PickleLen()
|
||||
length += r.CKey.PickleLen()
|
||||
return length
|
||||
}
|
||||
|
||||
// senderChain is a chain for receiving messages
|
||||
type receiverChain struct {
|
||||
RKey crypto.Curve25519PublicKey `json:"ratchet_key"`
|
||||
CKey chainKey `json:"chain_key"`
|
||||
}
|
||||
|
||||
const receiverChainPickleLength = crypto.Curve25519PubKeyLength + // Ratchet Key
|
||||
chainKeyPickleLength // CKey
|
||||
|
||||
// newReceiverChain returns a receiver chain initialized with chainKey and ratchet public key.
|
||||
func newReceiverChain(chain crypto.Curve25519PublicKey, ratchet crypto.Curve25519PublicKey) *receiverChain {
|
||||
return &receiverChain{
|
||||
|
|
@ -188,7 +183,7 @@ func (r *receiverChain) UnpickleLibOlm(value []byte) (int, error) {
|
|||
// PickleLibOlm encodes the chain into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (r receiverChain) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < r.PickleLen() {
|
||||
if len(target) < receiverChainPickleLength {
|
||||
return 0, fmt.Errorf("pickle sender chain: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written, err := r.RKey.PickleLibOlm(target)
|
||||
|
|
@ -203,19 +198,15 @@ func (r receiverChain) PickleLibOlm(target []byte) (int, error) {
|
|||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled chain will have.
|
||||
func (r receiverChain) PickleLen() int {
|
||||
length := r.RKey.PickleLen()
|
||||
length += r.CKey.PickleLen()
|
||||
return length
|
||||
}
|
||||
|
||||
// messageKey wraps the index and the key of a message
|
||||
type messageKey struct {
|
||||
Index uint32 `json:"index"`
|
||||
Key []byte `json:"key"`
|
||||
}
|
||||
|
||||
const messageKeyPickleLength = messageKeyLength + // Key
|
||||
libolmpickle.PickleUInt32Length // Index
|
||||
|
||||
// UnpickleLibOlm decodes the unencryted value and populates the message key accordingly. It returns the number of bytes read.
|
||||
func (m *messageKey) UnpickleLibOlm(value []byte) (int, error) {
|
||||
curPos := 0
|
||||
|
|
@ -237,7 +228,7 @@ func (m *messageKey) UnpickleLibOlm(value []byte) (int, error) {
|
|||
// PickleLibOlm encodes the message key into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (m messageKey) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < m.PickleLen() {
|
||||
if len(target) < messageKeyPickleLength {
|
||||
return 0, fmt.Errorf("pickle message key: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written := 0
|
||||
|
|
@ -249,10 +240,3 @@ func (m messageKey) PickleLibOlm(target []byte) (int, error) {
|
|||
written += libolmpickle.PickleUInt32(m.Index, target[written:])
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled message key will have.
|
||||
func (r messageKey) PickleLen() int {
|
||||
length := libolmpickle.PickleBytesLen(make([]byte, messageKeyLength))
|
||||
length += libolmpickle.PickleUInt32Len(r.Index)
|
||||
return length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,25 +388,25 @@ func (r Ratchet) PickleLibOlm(target []byte) (int, error) {
|
|||
|
||||
// PickleLen returns the actual number of bytes the pickled ratchet will have.
|
||||
func (r Ratchet) PickleLen() int {
|
||||
length := r.RootKey.PickleLen()
|
||||
length := crypto.Curve25519PubKeyLength // Root Key
|
||||
if r.SenderChains.IsSet {
|
||||
length += libolmpickle.PickleUInt32Len(1)
|
||||
length += r.SenderChains.PickleLen()
|
||||
length += libolmpickle.PickleUInt32Length // 1
|
||||
length += senderChainPickleLength // SenderChains
|
||||
} else {
|
||||
length += libolmpickle.PickleUInt32Len(0)
|
||||
length += libolmpickle.PickleUInt32Length // 0
|
||||
}
|
||||
length += libolmpickle.PickleUInt32Len(uint32(len(r.ReceiverChains)))
|
||||
length += len(r.ReceiverChains) * receiverChain{}.PickleLen()
|
||||
length += libolmpickle.PickleUInt32Len(uint32(len(r.SkippedMessageKeys)))
|
||||
length += len(r.SkippedMessageKeys) * skippedMessageKey{}.PickleLen()
|
||||
length += libolmpickle.PickleUInt32Length // ReceiverChains length
|
||||
length += len(r.ReceiverChains) * receiverChainPickleLength
|
||||
length += libolmpickle.PickleUInt32Length // SkippedMessageKeys length
|
||||
length += len(r.SkippedMessageKeys) * skippedMessageKeyPickleLen
|
||||
return length
|
||||
}
|
||||
|
||||
// PickleLen returns the minimum number of bytes the pickled ratchet must have.
|
||||
func (r Ratchet) PickleLenMin() int {
|
||||
length := r.RootKey.PickleLen()
|
||||
length += libolmpickle.PickleUInt32Len(0)
|
||||
length += libolmpickle.PickleUInt32Len(0)
|
||||
length += libolmpickle.PickleUInt32Len(0)
|
||||
length := crypto.Curve25519PubKeyLength // Root Key
|
||||
length += libolmpickle.PickleUInt32Length
|
||||
length += libolmpickle.PickleUInt32Length
|
||||
length += libolmpickle.PickleUInt32Length
|
||||
return length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ type skippedMessageKey struct {
|
|||
MKey messageKey `json:"message_key"`
|
||||
}
|
||||
|
||||
const skippedMessageKeyPickleLen = crypto.Curve25519PubKeyLength + // RKey
|
||||
messageKeyPickleLength // MKey
|
||||
|
||||
// UnpickleLibOlm decodes the unencryted value and populates the chain accordingly. It returns the number of bytes read.
|
||||
func (r *skippedMessageKey) UnpickleLibOlm(value []byte) (int, error) {
|
||||
curPos := 0
|
||||
|
|
@ -32,7 +35,7 @@ func (r *skippedMessageKey) UnpickleLibOlm(value []byte) (int, error) {
|
|||
// PickleLibOlm encodes the chain into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (r skippedMessageKey) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < r.PickleLen() {
|
||||
if len(target) < skippedMessageKeyPickleLen {
|
||||
return 0, fmt.Errorf("pickle sender chain: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written, err := r.RKey.PickleLibOlm(target)
|
||||
|
|
@ -46,10 +49,3 @@ func (r skippedMessageKey) PickleLibOlm(target []byte) (int, error) {
|
|||
written += writtenChain
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled chain will have.
|
||||
func (r skippedMessageKey) PickleLen() int {
|
||||
length := r.RKey.PickleLen()
|
||||
length += r.MKey.PickleLen()
|
||||
return length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/ed25519"
|
||||
"maunium.net/go/mautrix/crypto/goolm/cipher"
|
||||
"maunium.net/go/mautrix/crypto/goolm/crypto"
|
||||
"maunium.net/go/mautrix/crypto/goolm/goolmbase64"
|
||||
|
|
@ -19,6 +20,12 @@ import (
|
|||
const (
|
||||
megolmInboundSessionPickleVersionJSON byte = 1
|
||||
megolmInboundSessionPickleVersionLibOlm uint32 = 2
|
||||
|
||||
megolmInboundSessionPickleLength = libolmpickle.PickleUInt32Length + // Version
|
||||
megolm.RatchetPickleLength + // InitialRatchet
|
||||
megolm.RatchetPickleLength + // Ratchet
|
||||
ed25519.PublicKeySize + // SigningKey
|
||||
libolmpickle.PickleBoolLength // Verified
|
||||
)
|
||||
|
||||
// MegolmInboundSession stores information about the sessions of receive.
|
||||
|
|
@ -246,7 +253,7 @@ func (o *MegolmInboundSession) Pickle(key []byte) ([]byte, error) {
|
|||
if len(key) == 0 {
|
||||
return nil, olm.ErrNoKeyProvided
|
||||
}
|
||||
pickeledBytes := make([]byte, o.PickleLen())
|
||||
pickeledBytes := make([]byte, megolmInboundSessionPickleLength)
|
||||
written, err := o.PickleLibOlm(pickeledBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -260,7 +267,7 @@ func (o *MegolmInboundSession) Pickle(key []byte) ([]byte, error) {
|
|||
// PickleLibOlm encodes the session into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (o *MegolmInboundSession) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < o.PickleLen() {
|
||||
if len(target) < megolmInboundSessionPickleLength {
|
||||
return 0, fmt.Errorf("pickle MegolmInboundSession: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written := libolmpickle.PickleUInt32(megolmInboundSessionPickleVersionLibOlm, target)
|
||||
|
|
@ -283,16 +290,6 @@ func (o *MegolmInboundSession) PickleLibOlm(target []byte) (int, error) {
|
|||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled session will have.
|
||||
func (o *MegolmInboundSession) PickleLen() int {
|
||||
length := libolmpickle.PickleUInt32Len(megolmInboundSessionPickleVersionLibOlm)
|
||||
length += o.InitialRatchet.PickleLen()
|
||||
length += o.Ratchet.PickleLen()
|
||||
length += o.SigningKey.PickleLen()
|
||||
length += libolmpickle.PickleBoolLen(o.SigningKeyVerified)
|
||||
return length
|
||||
}
|
||||
|
||||
// FirstKnownIndex returns the first message index we know how to decrypt.
|
||||
func (s *MegolmInboundSession) FirstKnownIndex() uint32 {
|
||||
return s.InitialRatchet.Counter
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ import (
|
|||
const (
|
||||
megolmOutboundSessionPickleVersion byte = 1
|
||||
megolmOutboundSessionPickleVersionLibOlm uint32 = 1
|
||||
|
||||
MegolmOutboundSessionPickleLength = libolmpickle.PickleUInt32Length + // Version
|
||||
megolm.RatchetPickleLength + // Ratchet
|
||||
crypto.Ed25519KeyPairPickleLength // SigningKey
|
||||
)
|
||||
|
||||
// MegolmOutboundSession stores information about the sessions to send.
|
||||
|
|
@ -130,7 +134,7 @@ func (o *MegolmOutboundSession) Pickle(key []byte) ([]byte, error) {
|
|||
if len(key) == 0 {
|
||||
return nil, olm.ErrNoKeyProvided
|
||||
}
|
||||
pickeledBytes := make([]byte, o.PickleLen())
|
||||
pickeledBytes := make([]byte, MegolmOutboundSessionPickleLength)
|
||||
written, err := o.PickleLibOlm(pickeledBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -144,7 +148,7 @@ func (o *MegolmOutboundSession) Pickle(key []byte) ([]byte, error) {
|
|||
// PickleLibOlm encodes the session into target. target has to have a size of at least PickleLen() and is written to from index 0.
|
||||
// It returns the number of bytes written.
|
||||
func (o *MegolmOutboundSession) PickleLibOlm(target []byte) (int, error) {
|
||||
if len(target) < o.PickleLen() {
|
||||
if len(target) < MegolmOutboundSessionPickleLength {
|
||||
return 0, fmt.Errorf("pickle MegolmOutboundSession: %w", olm.ErrValueTooShort)
|
||||
}
|
||||
written := libolmpickle.PickleUInt32(megolmOutboundSessionPickleVersionLibOlm, target)
|
||||
|
|
@ -161,14 +165,6 @@ func (o *MegolmOutboundSession) PickleLibOlm(target []byte) (int, error) {
|
|||
return written, nil
|
||||
}
|
||||
|
||||
// PickleLen returns the number of bytes the pickled session will have.
|
||||
func (o *MegolmOutboundSession) PickleLen() int {
|
||||
length := libolmpickle.PickleUInt32Len(megolmOutboundSessionPickleVersionLibOlm)
|
||||
length += o.Ratchet.PickleLen()
|
||||
length += o.SigningKey.PickleLen()
|
||||
return length
|
||||
}
|
||||
|
||||
func (o *MegolmOutboundSession) SessionSharingMessage() ([]byte, error) {
|
||||
return o.Ratchet.SessionSharingMessage(o.SigningKey)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -458,22 +458,22 @@ func (o *OlmSession) PickleLibOlm(target []byte) (int, error) {
|
|||
|
||||
// PickleLen returns the actual number of bytes the pickled session will have.
|
||||
func (o *OlmSession) PickleLen() int {
|
||||
length := libolmpickle.PickleUInt32Len(olmSessionPickleVersionLibOlm)
|
||||
length += libolmpickle.PickleBoolLen(o.ReceivedMessage)
|
||||
length += o.AliceIdentityKey.PickleLen()
|
||||
length += o.AliceBaseKey.PickleLen()
|
||||
length += o.BobOneTimeKey.PickleLen()
|
||||
length := libolmpickle.PickleUInt32Length
|
||||
length += libolmpickle.PickleBoolLength
|
||||
length += crypto.Curve25519PubKeyLength // AliceIdentityKey
|
||||
length += crypto.Curve25519PubKeyLength // AliceBaseKey
|
||||
length += crypto.Curve25519PubKeyLength // BobOneTimeKey
|
||||
length += o.Ratchet.PickleLen()
|
||||
return length
|
||||
}
|
||||
|
||||
// PickleLenMin returns the minimum number of bytes the pickled session must have.
|
||||
func (o *OlmSession) PickleLenMin() int {
|
||||
length := libolmpickle.PickleUInt32Len(olmSessionPickleVersionLibOlm)
|
||||
length += libolmpickle.PickleBoolLen(o.ReceivedMessage)
|
||||
length += o.AliceIdentityKey.PickleLen()
|
||||
length += o.AliceBaseKey.PickleLen()
|
||||
length += o.BobOneTimeKey.PickleLen()
|
||||
length := libolmpickle.PickleUInt32Length
|
||||
length += libolmpickle.PickleBoolLength
|
||||
length += crypto.Curve25519PubKeyLength // AliceIdentityKey
|
||||
length += crypto.Curve25519PubKeyLength // AliceBaseKey
|
||||
length += crypto.Curve25519PubKeyLength // BobOneTimeKey
|
||||
length += o.Ratchet.PickleLenMin()
|
||||
return length
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue