double ratchet first implementation
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
ycc
2026-03-04 22:30:22 +01:00
parent c0dcfe997c
commit f4fb42d72e
11 changed files with 375 additions and 14 deletions

View File

@@ -1,11 +1,13 @@
package client
import (
"encoding/json"
"io"
"os"
"time"
"forge.redroom.link/yves/meowlib"
doubleratchet "github.com/status-im/doubleratchet"
"github.com/google/uuid"
"google.golang.org/protobuf/proto"
)
@@ -54,7 +56,14 @@ type Peer struct {
DbIds []string `json:"db_ids,omitempty"`
Type string `json:"type,omitempty"`
PersonnaeDbId string `json:"personnae_db_id,omitempty"`
dbPassword string
// Double Ratchet state
DrKpPublic string `json:"dr_kp_public,omitempty"`
DrKpPrivate string `json:"dr_kp_private,omitempty"`
DrRootKey string `json:"dr_root_key,omitempty"`
DrInitiator bool `json:"dr_initiator,omitempty"`
ContactDrPublicKey string `json:"contact_dr_public_key,omitempty"`
DrStateJson string `json:"dr_state_json,omitempty"`
dbPassword string
}
//
@@ -74,6 +83,8 @@ func (p *Peer) GetMyContact() *meowlib.ContactCard {
c.InvitationMessage = p.InvitationMessage
c.Name = p.MyName
c.SymetricKey = p.MySymKey
c.DrRootKey = p.DrRootKey
c.DrPublicKey = p.DrKpPublic
return &c
}
@@ -283,24 +294,61 @@ func (p *Peer) ProcessOutboundUserMessage(usermessage *meowlib.UserMessage) (*me
if err != nil {
return nil, err
}
// Symmetric encryption (outer layer, if symkey is configured)
// Symmetric encryption (middle layer, if symkey is configured)
symEncrypted, err := p.SymEncryptPayload(enc.Data)
if err != nil {
return nil, err
}
// Packing it
// Double Ratchet encryption (outermost layer, if DR is configured)
if p.DrRootKey != "" {
session, err := p.GetDRSession()
if err != nil {
return nil, err
}
drMsg, err := session.RatchetEncrypt(symEncrypted, nil)
if err != nil {
return nil, err
}
headerBytes, err := json.Marshal(drMsg.Header)
if err != nil {
return nil, err
}
packed := p.PackUserMessage(drMsg.Ciphertext, enc.Signature)
packed.DrHeader = headerBytes
return packed, nil
}
// No DR layer
packedMsg := p.PackUserMessage(symEncrypted, enc.Signature)
return packedMsg, nil
}
// ProcessInboundUserMessage is a helper function that decrypts and deserializes a user message
func (p *Peer) ProcessInboundUserMessage(message []byte, signature []byte) (*meowlib.UserMessage, error) {
// Symmetric decryption (outer layer, if symkey is configured)
symDecrypted, err := p.SymDecryptPayload(message)
func (p *Peer) ProcessInboundUserMessage(packed *meowlib.PackedUserMessage) (*meowlib.UserMessage, error) {
payload := packed.Payload
// Double Ratchet decryption (outermost layer), only when DR is configured and header present
if p.DrRootKey != "" && len(packed.DrHeader) > 0 {
session, err := p.GetDRSession()
if err != nil {
return nil, err
}
var header doubleratchet.MessageHeader
if err := json.Unmarshal(packed.DrHeader, &header); err != nil {
return nil, err
}
payload, err = session.RatchetDecrypt(
doubleratchet.Message{Header: header, Ciphertext: packed.Payload},
nil,
)
if err != nil {
return nil, err
}
}
// Symmetric decryption (middle layer, if symkey is configured)
symDecrypted, err := p.SymDecryptPayload(payload)
if err != nil {
return nil, err
}
dec, err := p.AsymDecryptMessage(symDecrypted, signature)
dec, err := p.AsymDecryptMessage(symDecrypted, packed.Signature)
if err != nil {
return nil, err
}