mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 16:14:02 +03:00
Add RPC structs for nonce
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
type RPC interface {
|
||||||
|
Bytes() []byte
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/binary"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/juju/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RPCNonceSeqNo = -2
|
||||||
|
|
||||||
|
rpcNonceLength = 16
|
||||||
|
rpcNonceKeySelectorLength = 4
|
||||||
|
rpcNonceCryptoTSLength = 4
|
||||||
|
rpcNonceTagLength = 4
|
||||||
|
rpcNonceCryptoAESLength = 4
|
||||||
|
|
||||||
|
rpcNonceRequestLength = rpcNonceTagLength + rpcNonceKeySelectorLength +
|
||||||
|
rpcNonceCryptoAESLength + rpcNonceCryptoTSLength + rpcNonceLength
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
rpcNonceTag = [rpcNonceTagLength]byte{0xaa, 0x87, 0xcb, 0x7a}
|
||||||
|
rpcNonceCryptoAESTag = [rpcNonceCryptoAESLength]byte{0x01, 0x00, 0x00, 0x00}
|
||||||
|
)
|
||||||
|
|
||||||
|
type RPCNonceRequest struct {
|
||||||
|
KeySelector [rpcNonceKeySelectorLength]byte
|
||||||
|
CryptoTS [rpcNonceCryptoTSLength]byte
|
||||||
|
Nonce [rpcNonceLength]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RPCNonceRequest) Bytes() []byte {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
buf.Grow(rpcNonceRequestLength)
|
||||||
|
|
||||||
|
buf.Write(rpcNonceTag[:])
|
||||||
|
buf.Write(r.KeySelector[:])
|
||||||
|
buf.Write(rpcNonceCryptoAESTag[:])
|
||||||
|
buf.Write(r.CryptoTS[:])
|
||||||
|
buf.Write(r.Nonce[:])
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRPCNonceRequest(proxySecret []byte) (*RPCNonceRequest, error) {
|
||||||
|
var nonce [rpcNonceLength]byte
|
||||||
|
var keySelector [rpcNonceKeySelectorLength]byte
|
||||||
|
var cryptoTS [rpcNonceCryptoTSLength]byte
|
||||||
|
|
||||||
|
if _, err := rand.Read(nonce[:]); err != nil {
|
||||||
|
return nil, errors.Annotate(err, "Cannot generate nonce")
|
||||||
|
}
|
||||||
|
copy(keySelector[:], proxySecret)
|
||||||
|
|
||||||
|
timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // 256 ^ 4 - do not know how to name
|
||||||
|
binary.LittleEndian.PutUint32(cryptoTS[:], uint32(timestamp))
|
||||||
|
|
||||||
|
return &RPCNonceRequest{
|
||||||
|
KeySelector: keySelector,
|
||||||
|
CryptoTS: cryptoTS,
|
||||||
|
Nonce: nonce,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/juju/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const rpcNonceResponseLength = rpcNonceRequestLength
|
||||||
|
|
||||||
|
type RPCNonceResponse struct {
|
||||||
|
RPCNonceRequest
|
||||||
|
|
||||||
|
RPCType [rpcNonceTagLength]byte
|
||||||
|
Crypto [rpcNonceCryptoAESLength]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RPCNonceResponse) Bytes() []byte {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
buf.Grow(rpcNonceResponseLength)
|
||||||
|
|
||||||
|
buf.Write(r.RPCType[:])
|
||||||
|
buf.Write(r.KeySelector[:])
|
||||||
|
buf.Write(r.Crypto[:])
|
||||||
|
buf.Write(r.CryptoTS[:])
|
||||||
|
buf.Write(r.Nonce[:])
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RPCNonceResponse) Valid(req *RPCNonceRequest) error {
|
||||||
|
if r.RPCType != rpcNonceTag {
|
||||||
|
return errors.New("Unexpected RPC type")
|
||||||
|
}
|
||||||
|
if r.Crypto != rpcNonceCryptoAESTag {
|
||||||
|
return errors.New("Unexpected crypto type")
|
||||||
|
}
|
||||||
|
if r.KeySelector != req.KeySelector {
|
||||||
|
return errors.New("Unexpected key selector")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRPCNonceResponse(data []byte) (*RPCNonceResponse, error) {
|
||||||
|
if len(data) != rpcNonceResponseLength {
|
||||||
|
return nil, errors.New("Unexpected message length")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := RPCNonceResponse{}
|
||||||
|
copy(resp.RPCType[:], data[:4])
|
||||||
|
copy(resp.KeySelector[:], data[4:8])
|
||||||
|
copy(resp.Crypto[:], data[8:12])
|
||||||
|
copy(resp.CryptoTS[:], data[12:16])
|
||||||
|
copy(resp.Nonce[:], data[16:])
|
||||||
|
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user