capnproto-rust icon indicating copy to clipboard operation
capnproto-rust copied to clipboard

Canonicalize message on receive

Open sanderpick opened this issue 1 year ago • 5 comments

We have a client written in Go that is sending a struct and a signature to a server that uses capnproto-rust:

interface Publication {
	push @0 (tx :Tx, signature :Data);
}

In order to create the signature, we're doing something like this in Go:

func (s *Streamer) sign(tx streamercapnp.Tx) ([]byte, error) {
	bytes, err := capnp.Canonicalize(tx.ToPtr().Struct())
	if err != nil {
		return []byte{}, fmt.Errorf("canonicalize: %s", err)
	}

	hash := sha256.Sum256(bytes)
	signature, err := crypto.Sign(hash[:], s.privateKey)
	if err != nil {
		return []byte{}, fmt.Errorf("sign: %s", err)
	}

	return signature, nil
}

Now, on the Rust side we need to verify the signature. My thought was that we'd need to canonicalize Tx to get the signature payload. I see canonicalize test (https://github.com/capnproto/capnproto-rust/blob/master/capnp/tests/canonicalize.rs), but having a hard time understanding how I can do that in the server's push implementation. eg,

fn push(
    &mut self,
    params: publication::PushParams,
    mut results: publication::PushResults,
) -> Promise<(), Error> {
    let args = pry!(params.get());
    let txn = args.get_tx().unwrap();
    let sig = args.get_signature().unwrap();

    // how to get canonical Tx raw bytes? 
    
    Promise::ok(())
}

Thank you!

sanderpick avatar Aug 24 '23 18:08 sanderpick