2018-10-31 11:17:51 +01:00
|
|
|
package datastructures
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2021-01-04 14:15:12 +01:00
|
|
|
|
|
|
|
"git.cacert.org/cacert-gosigner/shared"
|
2018-10-31 11:17:51 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type SignerResponse struct {
|
|
|
|
Version uint8
|
2021-01-04 14:15:12 +01:00
|
|
|
Action shared.Action
|
2018-10-31 11:17:51 +01:00
|
|
|
Reserved1 uint8
|
|
|
|
Reserved2 uint8
|
2021-01-05 19:59:43 +01:00
|
|
|
Content []byte
|
|
|
|
Argument1 []byte
|
|
|
|
Argument2 []byte
|
2018-10-31 11:17:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func SignerResponseFromData(lengthBytes []byte, blockData []byte, checkSum byte) (*SignerResponse, error) {
|
2020-04-17 19:39:01 +02:00
|
|
|
if len(blockData) < 3 {
|
|
|
|
return nil, errors.New("begin of structure corrupt")
|
|
|
|
}
|
2018-10-31 11:17:51 +01:00
|
|
|
|
2020-04-17 19:39:01 +02:00
|
|
|
offset := 0
|
|
|
|
headerLength := Decode24BitLength(blockData[offset : offset+3])
|
|
|
|
offset += 3
|
|
|
|
headerBytes := blockData[offset : offset+headerLength]
|
|
|
|
offset += headerLength
|
2018-10-31 11:17:51 +01:00
|
|
|
|
2021-01-05 19:59:43 +01:00
|
|
|
content := make([][]byte, 3)
|
2020-04-17 19:39:01 +02:00
|
|
|
for offset < len(blockData) {
|
|
|
|
dataLength := Decode24BitLength(blockData[offset : offset+3])
|
|
|
|
if len(blockData)-3 < dataLength {
|
|
|
|
return nil, errors.New("structure cut off")
|
|
|
|
}
|
|
|
|
offset += 3
|
2021-01-05 19:59:43 +01:00
|
|
|
content = append(content, blockData[offset:offset+dataLength])
|
2020-04-17 19:39:01 +02:00
|
|
|
offset += dataLength
|
|
|
|
}
|
2018-10-31 11:17:51 +01:00
|
|
|
|
|
|
|
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],
|
2021-01-04 14:15:12 +01:00
|
|
|
Action: shared.Action(headerBytes[1]),
|
2018-10-31 11:17:51 +01:00
|
|
|
Reserved1: headerBytes[2],
|
|
|
|
Reserved2: headerBytes[3],
|
2021-01-05 19:59:43 +01:00
|
|
|
Content: content[0],
|
|
|
|
Argument1: content[1],
|
|
|
|
Argument2: content[2],
|
2018-10-31 11:17:51 +01:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r SignerResponse) Serialize() []byte {
|
|
|
|
headerBytes := []byte{r.Version, byte(r.Action), r.Reserved1, r.Reserved2}
|
|
|
|
blockBytes := bytes.Join([][]byte{
|
2021-01-04 20:39:35 +01:00
|
|
|
Encode24BitLength(headerBytes), headerBytes,
|
2021-01-05 19:59:43 +01:00
|
|
|
Encode24BitLength(r.Content), r.Content,
|
|
|
|
Encode24BitLength(r.Argument1), r.Argument1,
|
|
|
|
Encode24BitLength(r.Argument2), r.Argument2,
|
2018-10-31 11:17:51 +01:00
|
|
|
}, []byte{})
|
2021-01-04 20:39:35 +01:00
|
|
|
return bytes.Join([][]byte{Encode24BitLength(blockBytes), blockBytes}, []byte{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewNulResponse(version byte) *SignerResponse {
|
|
|
|
return &SignerResponse{
|
2021-01-05 19:59:43 +01:00
|
|
|
Version: version,
|
|
|
|
Action: shared.ActionNul,
|
|
|
|
Content: []byte{},
|
|
|
|
Argument1: []byte{},
|
|
|
|
Argument2: []byte{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRevokeResponse(version byte, content []byte) *SignerResponse {
|
|
|
|
return &SignerResponse{
|
|
|
|
Version: version,
|
|
|
|
Action: shared.ActionRevoke,
|
|
|
|
Content: content,
|
|
|
|
Argument1: []byte{},
|
|
|
|
Argument2: []byte{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewSignResponse(version byte, content []byte) *SignerResponse {
|
|
|
|
return &SignerResponse{
|
|
|
|
Version: version,
|
|
|
|
Action: shared.ActionSign,
|
|
|
|
Content: content,
|
|
|
|
Argument1: []byte{},
|
|
|
|
Argument2: []byte{},
|
2021-01-04 20:39:35 +01:00
|
|
|
}
|
2018-10-31 11:17:51 +01:00
|
|
|
}
|