cacert-gosigner/datastructures/signerresponse.go

72 lines
1.9 KiB
Go

package datastructures
import (
"bytes"
"errors"
"fmt"
"git.cacert.org/cacert-gosigner/shared"
)
type SignerResponse struct {
Version uint8
Action shared.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: shared.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{})
}