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