Initial signer rewrite in Go
This commit is contained in:
commit
a89275a8e4
9 changed files with 557 additions and 0 deletions
28
datastructures/common.go
Normal file
28
datastructures/common.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package datastructures
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
type Action uint8
|
||||
|
||||
const ActionNul = Action(0)
|
||||
|
||||
func encode24BitLength(data []byte) []byte {
|
||||
lengthBytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(lengthBytes, uint32(len(data)))
|
||||
return lengthBytes[1:]
|
||||
}
|
||||
|
||||
// calculate length from 24 bits of data in network byte order
|
||||
func decode24BitLength(bytes []byte) int {
|
||||
return int(binary.BigEndian.Uint32([]byte{0x0, bytes[0], bytes[1], bytes[2]}))
|
||||
}
|
||||
|
||||
func CalculateXorCheckSum(byteBlocks [][]byte) byte {
|
||||
var result byte = 0x0
|
||||
for _, byteBlock := range byteBlocks {
|
||||
for _, b := range byteBlock {
|
||||
result ^= b
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
80
datastructures/signerrequest.go
Normal file
80
datastructures/signerrequest.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package datastructures
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SignerRequest struct {
|
||||
Version uint8
|
||||
Action Action
|
||||
System uint8
|
||||
Root uint8
|
||||
Configuration uint8
|
||||
Parameter1 uint8
|
||||
Parameter2 uint16
|
||||
Parameter3 uint8
|
||||
Content1 string
|
||||
Content2 string
|
||||
Content3 string
|
||||
}
|
||||
|
||||
func SignerRequestFromData(lengthBytes []byte, blockData []byte, checkSum byte) (*SignerRequest, error) {
|
||||
headerLength := decode24BitLength(blockData[0:3])
|
||||
headerBytes := blockData[3 : 3+headerLength]
|
||||
|
||||
contentBytes := blockData[3+headerLength:]
|
||||
content1Length := decode24BitLength(contentBytes[0:3])
|
||||
content1 := string(contentBytes[3 : 3+content1Length])
|
||||
|
||||
content2Offset := 3 + content1Length
|
||||
content2Length := decode24BitLength(contentBytes[content2Offset : content2Offset+3])
|
||||
content2 := string(contentBytes[3+content2Offset : 3+content2Offset+content2Length])
|
||||
|
||||
content3Offset := 3 + content2Offset + content2Length
|
||||
content3Length := decode24BitLength(contentBytes[content3Offset : content3Offset+3])
|
||||
content3 := string(contentBytes[3+content3Offset : 3+content3Offset+content3Length])
|
||||
|
||||
calculated := CalculateXorCheckSum([][]byte{lengthBytes, blockData})
|
||||
if checkSum != calculated {
|
||||
return nil, errors.New(fmt.Sprintf("invalid checksum expected 0x%x got 0x%x", calculated, checkSum))
|
||||
}
|
||||
return &SignerRequest{
|
||||
Version: headerBytes[0],
|
||||
Action: Action(headerBytes[1]),
|
||||
System: headerBytes[2],
|
||||
Root: headerBytes[3],
|
||||
Configuration: headerBytes[4],
|
||||
Parameter1: headerBytes[5],
|
||||
Parameter2: binary.BigEndian.Uint16([]byte{headerBytes[6], headerBytes[7]}),
|
||||
Parameter3: headerBytes[8],
|
||||
Content1: content1,
|
||||
Content2: content2,
|
||||
Content3: content3,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r SignerRequest) Serialize() []byte {
|
||||
parameter2Bytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(parameter2Bytes, r.Parameter2)
|
||||
headerBytes := bytes.Join([][]byte{
|
||||
{r.Version, byte(r.Action), r.System, r.Root, r.Configuration, r.Parameter1},
|
||||
parameter2Bytes, {r.Parameter3}}, []byte{})
|
||||
content1Bytes := []byte(r.Content1)
|
||||
content2Bytes := []byte(r.Content2)
|
||||
content3Bytes := []byte(r.Content3)
|
||||
blockBytes := bytes.Join([][]byte{
|
||||
encode24BitLength(headerBytes), headerBytes,
|
||||
encode24BitLength(content1Bytes), content1Bytes,
|
||||
encode24BitLength(content2Bytes), content2Bytes,
|
||||
encode24BitLength(content3Bytes), content3Bytes,
|
||||
}, []byte{})
|
||||
return bytes.Join([][]byte{encode24BitLength(blockBytes), blockBytes}, []byte{})
|
||||
}
|
||||
|
||||
func NewNulRequest() *SignerRequest {
|
||||
return &SignerRequest{Version: 1, Action: ActionNul, Content1: time.Now().UTC().Format("010203042006.05")}
|
||||
}
|
63
datastructures/signerresponse.go
Normal file
63
datastructures/signerresponse.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
package datastructures
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type SignerResponse struct {
|
||||
Version uint8
|
||||
Action Action
|
||||
Reserved1 uint8
|
||||
Reserved2 uint8
|
||||
Content1 string
|
||||
Content2 string
|
||||
Content3 string
|
||||
}
|
||||
|
||||
func SignerResponseFromData(lengthBytes []byte, blockData []byte, checkSum byte) (*SignerResponse, error) {
|
||||
headerLength := decode24BitLength(lengthBytes)
|
||||
headerBytes := blockData[3 : 3+headerLength]
|
||||
|
||||
contentBytes := blockData[3+headerLength:]
|
||||
content1Length := decode24BitLength(contentBytes[0:3])
|
||||
content1 := string(contentBytes[3 : 3+content1Length])
|
||||
|
||||
content2Offset := 3 + content1Length
|
||||
content2Length := decode24BitLength(contentBytes[content2Offset : content2Offset+3])
|
||||
content2 := string(contentBytes[3+content2Offset : 3+content2Offset+content2Length])
|
||||
|
||||
content3Offset := 3 + content2Offset + content2Length
|
||||
content3Length := decode24BitLength(contentBytes[content3Offset : content3Offset+3])
|
||||
content3 := string(contentBytes[3+content3Offset : 3+content3Offset+content3Length])
|
||||
|
||||
calculated := CalculateXorCheckSum([][]byte{lengthBytes, blockData})
|
||||
if checkSum != calculated {
|
||||
return nil, errors.New(fmt.Sprintf("invalid checksum expected 0x%x got 0x%x", calculated, checkSum))
|
||||
}
|
||||
|
||||
return &SignerResponse{
|
||||
Version: headerBytes[0],
|
||||
Action: Action(headerBytes[1]),
|
||||
Reserved1: headerBytes[2],
|
||||
Reserved2: headerBytes[3],
|
||||
Content1: content1,
|
||||
Content2: content2,
|
||||
Content3: content3,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r SignerResponse) Serialize() []byte {
|
||||
headerBytes := []byte{r.Version, byte(r.Action), r.Reserved1, r.Reserved2}
|
||||
content1Bytes := []byte(r.Content1)
|
||||
content2Bytes := []byte(r.Content2)
|
||||
content3Bytes := []byte(r.Content3)
|
||||
blockBytes := bytes.Join([][]byte{
|
||||
encode24BitLength(headerBytes), headerBytes,
|
||||
encode24BitLength(content1Bytes), content1Bytes,
|
||||
encode24BitLength(content2Bytes), content2Bytes,
|
||||
encode24BitLength(content3Bytes), content3Bytes,
|
||||
}, []byte{})
|
||||
return bytes.Join([][]byte{encode24BitLength(blockBytes), blockBytes}, []byte{})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue