cacert-gosigner/datastructures/signerrequest.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

86 lines
2.7 KiB
Go

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
}
const protocolVersion = 1
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: protocolVersion,
Action: ActionNul,
Content1: time.Now().UTC().Format("010203042006.05"),
}
}