42d1e6e991
Add a main loop, move I/O code into io.go, move configuration into config.go. Use shared.Decode24BitLength instead of manually decoding block lengths. Fix response block decoding and checksum validation. Add constants for commonly used byte values and use these in the signer and the client.
69 lines
1.9 KiB
Go
69 lines
1.9 KiB
Go
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) {
|
|
if len(blockData) < 3 {
|
|
return nil, errors.New("begin of structure corrupt")
|
|
}
|
|
|
|
offset := 0
|
|
headerLength := Decode24BitLength(blockData[offset : offset+3])
|
|
offset += 3
|
|
headerBytes := blockData[offset : offset+headerLength]
|
|
offset += headerLength
|
|
|
|
content := make([]string, 3)
|
|
for offset < len(blockData) {
|
|
dataLength := Decode24BitLength(blockData[offset : offset+3])
|
|
if len(blockData)-3 < dataLength {
|
|
return nil, errors.New("structure cut off")
|
|
}
|
|
offset += 3
|
|
content = append(content, string(blockData[offset:offset+dataLength]))
|
|
offset += dataLength
|
|
}
|
|
|
|
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: content[0],
|
|
Content2: content[1],
|
|
Content3: content[2],
|
|
}, 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{})
|
|
}
|