cacert-gosigner/datastructures/signerresponse.go
Jan Dittberner 42d1e6e991 Refactor client into separate files
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.
2020-04-17 19:39:01 +02:00

70 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{})
}