From 4319ba39a90023cf0cce771add71277fae8d96df Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Tue, 9 Jul 2024 18:51:22 +0200 Subject: [PATCH] Fixed TicketV2 validation --- edge/device_ticket.go | 58 +++++++++++++++++++++++++++---------------- edge/protocol.go | 4 ++- rpc/client.go | 7 +++--- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/edge/device_ticket.go b/edge/device_ticket.go index 5e8a60e..5b1d28f 100644 --- a/edge/device_ticket.go +++ b/edge/device_ticket.go @@ -44,8 +44,19 @@ type DeviceTicket struct { // ValidateValues checks length of byte[] arrays and returns an error message func (ct *DeviceTicket) ValidateValues() error { - if len(ct.BlockHash) != 32 { - return fmt.Errorf("blockhash must be 32 bytes") + if ct.Version == 1 { + if len(ct.BlockHash) != 32 { + return fmt.Errorf("blockhash must be 32 bytes") + } + } else if ct.Version == 2 { + if ct.Epoch == 0 { + return fmt.Errorf("epoch must be greater than 0") + } + if ct.ChainID == 0 { + return fmt.Errorf("chainid must be greater than 0") + } + } else { + return fmt.Errorf("version must be 1 or 2") } return nil } @@ -55,7 +66,8 @@ func (ct *DeviceTicket) HashWithoutSig() ([]byte, error) { if err := ct.ValidateValues(); err != nil { return nil, err } - return crypto.Sha3Hash(ct.arrayBlob()[:192]), nil + blob := ct.arrayBlob() + return crypto.Sha3Hash(blob[:len(blob)-len(ct.DeviceSig)]), nil } // Hash returns hash of device object @@ -67,24 +79,28 @@ func (ct *DeviceTicket) Hash() ([]byte, error) { } func (ct *DeviceTicket) arrayBlob() []byte { - // From DiodeRegistry.sol: - // bytes32[] memory message = new bytes32[](6); - // message[0] = blockhash(blockHeight); - // message[1] = bytes32(fleetContract); - // message[2] = bytes32(nodeAddress); - // message[3] = bytes32(totalConnections); - // message[4] = bytes32(totalBytes); - // message[5] = localAddress; - - msg := [32*6 + 65]byte{} - copy(msg[0:32], ct.BlockHash) - copy(msg[44:64], ct.FleetAddr[:]) - copy(msg[76:96], ct.ServerID[:]) - binary.BigEndian.PutUint64(msg[120:128], ct.TotalConnections) - binary.BigEndian.PutUint64(msg[152:160], ct.TotalBytes) - copy(msg[160:192], crypto.Sha256(ct.LocalAddr)) - copy(msg[192:], ct.DeviceSig) - return msg[:192+len(ct.DeviceSig)] + if ct.Version == 2 { + msg := [32*7 + 65]byte{} + binary.BigEndian.PutUint64(msg[24:32], ct.ChainID) + binary.BigEndian.PutUint64(msg[56:64], ct.Epoch) + copy(msg[76:96], ct.FleetAddr[:]) + copy(msg[108:128], ct.ServerID[:]) + binary.BigEndian.PutUint64(msg[152:160], ct.TotalConnections) + binary.BigEndian.PutUint64(msg[184:192], ct.TotalBytes) + copy(msg[192:224], crypto.Sha256(ct.LocalAddr)) + copy(msg[224:], ct.DeviceSig) + return msg[:224+len(ct.DeviceSig)] + } else { + msg := [32*6 + 65]byte{} + copy(msg[0:32], ct.BlockHash) + copy(msg[44:64], ct.FleetAddr[:]) + copy(msg[76:96], ct.ServerID[:]) + binary.BigEndian.PutUint64(msg[120:128], ct.TotalConnections) + binary.BigEndian.PutUint64(msg[152:160], ct.TotalBytes) + copy(msg[160:192], crypto.Sha256(ct.LocalAddr)) + copy(msg[192:], ct.DeviceSig) + return msg[:192+len(ct.DeviceSig)] + } } // Sign ticket with given ecdsa private key diff --git a/edge/protocol.go b/edge/protocol.go index 6f36a71..6155cb9 100644 --- a/edge/protocol.go +++ b/edge/protocol.go @@ -204,6 +204,7 @@ func parseDeviceTicketResponse(buffer []byte) (interface{}, error) { } err = ErrTicketTooLow ticket := DeviceTicket{ + Version: 1, BlockHash: response.Payload.BlockHash, TotalConnections: response.Payload.TotalConnections, TotalBytes: response.Payload.TotalBytes, @@ -221,7 +222,8 @@ func parseDeviceTicketResponse(buffer []byte) (interface{}, error) { } err = ErrTicketTooOld ticket := DeviceTicket{ - Err: err, + Version: 1, + Err: err, } return ticket, nil } diff --git a/rpc/client.go b/rpc/client.go index bbcc4ff..cdcd077 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -603,6 +603,7 @@ func (client *Client) newTicket() (*edge.DeviceTicket, error) { lvbn, lvbh := client.LastValid() ticket := &edge.DeviceTicket{ + Version: 1, ServerID: serverID, BlockNumber: lvbn, BlockHash: lvbh[:], @@ -664,16 +665,14 @@ func (client *Client) submitTicket(ticket *edge.DeviceTicket) error { if !lastTicket.ValidateDeviceSig(client.config.ClientAddr) { lastTicket.LocalAddr = util.DecodeForce(lastTicket.LocalAddr) - } - if lastTicket.ValidateDeviceSig(client.config.ClientAddr) { + client.Log().Warn("received fake ticket.. last_ticket=%v", lastTicket) + } else { client.s.setTotalBytes(lastTicket.TotalBytes + 1024) client.s.totalConnections = lastTicket.TotalConnections + 1 err = client.SubmitNewTicket() if err != nil { client.Log().Error("failed to re-submit ticket: %v", err) } - } else { - client.Log().Warn("received fake ticket.. last_ticket=%v", lastTicket) } } else if lastTicket.Err == edge.ErrTicketTooOld { client.Log().Info("received too old ticket")