matrix-capnproto-fed

What if Matrix was written using Cap'n'proto and a RPC federation API?
git clone git://archive.git.mtrnord.blog/MTRNord/matrix-capnproto-fed.git
Log | Files | Refs | README | LICENSE

rpc_server.go (4087B)


      1 package rpcserver
      2 
      3 import (
      4 	"bytes"
      5 	"context"
      6 	"crypto/ed25519"
      7 	"encoding/base64"
      8 	"log"
      9 	"time"
     10 
     11 	capnp "capnproto.org/go/capnp/v3"
     12 
     13 	protocol "github.com/MTRNord/matrix_protobuf_fed/proto/federation/v1"
     14 	"github.com/MTRNord/matrix_protobuf_fed/proto/federation/v1/types"
     15 )
     16 
     17 type SigningKeyWrapper struct {
     18 	*protocol.MatrixFederation
     19 	entityName string
     20 	keyID      KeyID
     21 	privateKey ed25519.PrivateKey
     22 }
     23 
     24 type RPCMatrixServer struct {
     25 	signing_key SigningKeyWrapper
     26 }
     27 
     28 func NewServer() RPCMatrixServer {
     29 	// Check JSON verification using the test vectors from https://matrix.org/docs/spec/appendices.html
     30 	seed, err := base64.RawStdEncoding.DecodeString("YJDBA9Xnr2sVqXD9Vj7XVUnmFZcZrlw8Md7kMW+3XA1")
     31 	if err != nil {
     32 		log.Fatal(err)
     33 	}
     34 	random := bytes.NewBuffer(seed)
     35 	entityName := "domain"
     36 	keyID := KeyID("ed25519:1")
     37 
     38 	_, privateKey, err := ed25519.GenerateKey(random)
     39 	if err != nil {
     40 		log.Fatal(err)
     41 	}
     42 
     43 	return RPCMatrixServer{
     44 		signing_key: SigningKeyWrapper{
     45 			entityName: entityName,
     46 			keyID:      keyID,
     47 			privateKey: privateKey,
     48 		},
     49 	}
     50 }
     51 
     52 func (s RPCMatrixServer) GetVersion(ctx context.Context, call protocol.MatrixFederation_getVersion) error {
     53 	call.Go()
     54 	res, err := call.AllocResults() // Allocate the results struct
     55 	if err != nil {
     56 		return err
     57 	}
     58 
     59 	version, err := res.NewServerVersion()
     60 	if err != nil {
     61 		return err
     62 	}
     63 	version.SetName("Matrix Federation Cap'n'Proto RPC Proxy")
     64 	version.SetVersion("0.1.0")
     65 
     66 	return nil
     67 }
     68 
     69 func (s RPCMatrixServer) GetKeys(ctx context.Context, call protocol.MatrixFederation_getKeys) error {
     70 	call.Go()
     71 
     72 	client := call.Args().Callback()
     73 	defer client.Release()
     74 
     75 	err := client.Write(ctx, func(p protocol.StreamCallback_write_Params) error {
     76 		log.Println("Sending server keys metadata response...")
     77 
     78 		response, err := types.NewServerKeysResponse(p.Segment())
     79 		if err != nil {
     80 			return err
     81 		}
     82 		p.SetValue(response.ToPtr())
     83 
     84 		metadata, err := response.NewMetadata()
     85 		if err != nil {
     86 			return err
     87 		}
     88 		metadata.SetServerName("placeholder")
     89 		metadata.SetValidUntilTS(time.Now().UTC().Add(time.Hour * 24).Unix())
     90 
     91 		metadata_bytes, err := capnp.Canonicalize(capnp.Struct(metadata))
     92 		if err != nil {
     93 			return err
     94 		}
     95 		signatures, err := response.NewSignatures(1)
     96 		if err != nil {
     97 			return err
     98 		}
     99 		err = SignCapnproto("placeholder", "placeholder", s.signing_key.privateKey, metadata_bytes, &signatures)
    100 		if err != nil {
    101 			return err
    102 		}
    103 		return response.SetSignatures(signatures)
    104 	})
    105 	if err != nil {
    106 		return err
    107 	}
    108 
    109 	err = client.Write(ctx, func(p protocol.StreamCallback_write_Params) error {
    110 		log.Println("Sending server keys verify_keys response...")
    111 
    112 		response, err := types.NewServerKeysResponse(p.Segment())
    113 		if err != nil {
    114 			return err
    115 		}
    116 		p.SetValue(response.ToPtr())
    117 
    118 		verify_keys_raw, err := response.NewVerifyKeys()
    119 		if err != nil {
    120 			return err
    121 		}
    122 		verify_keys := FromMap(&verify_keys_raw, 1)
    123 		key, err := capnp.NewText(verify_keys.Segment(), "placeholder")
    124 		if err != nil {
    125 			return err
    126 		}
    127 
    128 		log.Println("Original Key bytes:", s.signing_key.privateKey.Public().(ed25519.PublicKey))
    129 		data, err := capnp.NewData(verify_keys.Segment(), s.signing_key.privateKey.Public().(ed25519.PublicKey))
    130 		if err != nil {
    131 			return err
    132 		}
    133 		verify_keys.AddEntry(key.ToPtr(), data.ToPtr())
    134 
    135 		verify_keys_bytes, err := capnp.Canonicalize(capnp.Struct(verify_keys_raw))
    136 		if err != nil {
    137 			return err
    138 		}
    139 		signatures, err := response.NewSignatures(1)
    140 		if err != nil {
    141 			return err
    142 		}
    143 		err = SignCapnproto("placeholder", "placeholder", s.signing_key.privateKey, verify_keys_bytes, &signatures)
    144 		if err != nil {
    145 			return err
    146 		}
    147 		return response.SetSignatures(signatures)
    148 	})
    149 	if err != nil {
    150 		return err
    151 	}
    152 
    153 	_, release := client.Done(ctx, nil)
    154 	defer release()
    155 
    156 	if err := client.WaitStreaming(); err != nil {
    157 		return err
    158 	}
    159 
    160 	return err
    161 }
    162 
    163 func (s RPCMatrixServer) SendTransactions(context.Context, protocol.MatrixFederation_sendTransactions) error {
    164 	return nil
    165 }
    166 
    167 func (s RPCMatrixServer) Backfill(context.Context, protocol.MatrixFederation_backfill) error {
    168 	return nil
    169 }