Protocol improvements
- add a client generated command ID for tracing commands and responses - define protocol delimiter in protocol.CobsDelimiter - apply code simplifications suggested by golangci-lint - add Makefile - add compile time build information for signer binary - make sure that dependencies for msgpackgen survive go mod tidy - extract MsgPackHandler into its own file - add CRL number to fetch CRL response - remove port.Flush() to avoid removing written data before it reaches the client
This commit is contained in:
parent
8e443bd8b4
commit
f0d456dd13
11 changed files with 482 additions and 643 deletions
26
Makefile
Normal file
26
Makefile
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
GOFILES := $(shell find -type f -name '*.go')
|
||||||
|
BUILD_TIME := $(shell date --rfc-3339=seconds)
|
||||||
|
COMMIT := $(shell git show-ref --head --abbrev=8 HEAD|cut -d ' ' -f 1)
|
||||||
|
VERSION := $(shell git describe --always --dirty)
|
||||||
|
|
||||||
|
all: pkg/messages/resolver.msgpackgen.go lint test clientsim signer
|
||||||
|
|
||||||
|
pkg/messages/resolver.msgpackgen.go: pkg/messages/messages.go
|
||||||
|
go generate $<
|
||||||
|
|
||||||
|
lint:
|
||||||
|
golangci-lint run
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test -race ./...
|
||||||
|
|
||||||
|
clientsim: $(GOFILES)
|
||||||
|
go build -race ./cmd/clientsim
|
||||||
|
|
||||||
|
signer: $(GOFILES)
|
||||||
|
go build -race -ldflags="-X 'main.date=$(BUILD_TIME)' -X 'main.commit=$(COMMIT)' -X 'main.version=$(VERSION)'" ./cmd/signer
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f signer clientsim pkg/messages/resolver.msgpackgen.go
|
||||||
|
|
||||||
|
.PHONY: test lint all clean
|
|
@ -37,7 +37,7 @@ import (
|
||||||
"git.cacert.org/cacert-gosigner/pkg/messages"
|
"git.cacert.org/cacert-gosigner/pkg/messages"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cobsConfig = cobs.Config{SpecialByte: 0x00, Delimiter: true, EndingSave: true}
|
var cobsConfig = cobs.Config{SpecialByte: protocol.CobsDelimiter, Delimiter: true, EndingSave: true}
|
||||||
|
|
||||||
type protocolState int8
|
type protocolState int8
|
||||||
|
|
||||||
|
@ -82,8 +82,8 @@ func (g *TestCommandGenerator) CmdAnnouncement() ([]byte, error) {
|
||||||
g.lock.Lock()
|
g.lock.Lock()
|
||||||
defer g.lock.Unlock()
|
defer g.lock.Unlock()
|
||||||
|
|
||||||
select {
|
g.currentCommand = <-g.commands
|
||||||
case g.currentCommand = <-g.commands:
|
|
||||||
announceData, err := msgpack.Marshal(g.currentCommand.Announce)
|
announceData, err := msgpack.Marshal(g.currentCommand.Announce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not marshal command annoucement: %w", err)
|
return nil, fmt.Errorf("could not marshal command annoucement: %w", err)
|
||||||
|
@ -92,7 +92,6 @@ func (g *TestCommandGenerator) CmdAnnouncement() ([]byte, error) {
|
||||||
g.logger.WithField("announcement", &g.currentCommand.Announce).Info("write command announcement")
|
g.logger.WithField("announcement", &g.currentCommand.Announce).Info("write command announcement")
|
||||||
|
|
||||||
return announceData, nil
|
return announceData, nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *TestCommandGenerator) CmdData() ([]byte, error) {
|
func (g *TestCommandGenerator) CmdData() ([]byte, error) {
|
||||||
|
@ -138,13 +137,15 @@ func (g *TestCommandGenerator) HandleResponse(frame []byte) error {
|
||||||
return fmt.Errorf("unmarshal failed: %w", err)
|
return fmt.Errorf("unmarshal failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
g.currentResponse.Response = response
|
g.currentResponse.Response = &response
|
||||||
case messages.RespFetchCRL:
|
case messages.RespFetchCRL:
|
||||||
var response messages.FetchCRLResponse
|
var response messages.FetchCRLResponse
|
||||||
|
|
||||||
if err := msgpack.Unmarshal(frame, &response); err != nil {
|
if err := msgpack.Unmarshal(frame, &response); err != nil {
|
||||||
return fmt.Errorf("unmarshal failed: %w", err)
|
return fmt.Errorf("unmarshal failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g.currentResponse.Response = &response
|
||||||
}
|
}
|
||||||
|
|
||||||
g.logger.WithField(
|
g.logger.WithField(
|
||||||
|
@ -159,14 +160,27 @@ func (g *TestCommandGenerator) HandleResponse(frame []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error {
|
func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error {
|
||||||
const healthInterval = 10 * time.Second
|
const (
|
||||||
|
healthInterval = 5 * time.Second
|
||||||
|
startPause = 3 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
announce *messages.CommandAnnounce
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
g.logger.Info("start generating commands")
|
g.logger.Info("start generating commands")
|
||||||
|
|
||||||
time.Sleep(healthInterval)
|
time.Sleep(startPause)
|
||||||
|
|
||||||
|
announce, err = messages.BuildCommandAnnounce(messages.CmdFetchCRL)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("build command announce failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
g.commands <- &protocol.Command{
|
g.commands <- &protocol.Command{
|
||||||
Announce: messages.BuildCommandAnnounce(messages.CmdFetchCRL),
|
Announce: announce,
|
||||||
Command: &messages.FetchCRLCommand{IssuerID: "sub-ecc_person_2022"},
|
Command: &messages.FetchCRLCommand{IssuerID: "sub-ecc_person_2022"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +195,13 @@ func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
|
announce, err = messages.BuildCommandAnnounce(messages.CmdHealth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("build command announce failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
g.commands <- &protocol.Command{
|
g.commands <- &protocol.Command{
|
||||||
Announce: messages.BuildCommandAnnounce(messages.CmdHealth),
|
Announce: announce,
|
||||||
Command: &messages.HealthCommand{},
|
Command: &messages.HealthCommand{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +222,9 @@ func (c *clientSimulator) readFrames() error {
|
||||||
const readInterval = 50 * time.Millisecond
|
const readInterval = 50 * time.Millisecond
|
||||||
|
|
||||||
var frame []byte
|
var frame []byte
|
||||||
|
|
||||||
buffer := &bytes.Buffer{}
|
buffer := &bytes.Buffer{}
|
||||||
|
|
||||||
delimiter := []byte{cobsConfig.SpecialByte}
|
delimiter := []byte{cobsConfig.SpecialByte}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -231,6 +252,8 @@ func (c *clientSimulator) readFrames() error {
|
||||||
rest := buffer.Bytes()
|
rest := buffer.Bytes()
|
||||||
|
|
||||||
if !bytes.Contains(rest, delimiter) {
|
if !bytes.Contains(rest, delimiter) {
|
||||||
|
c.logger.Tracef("read data does not contain the delimiter %x", delimiter)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +277,8 @@ func (c *clientSimulator) readFrames() error {
|
||||||
c.logger.Tracef("frame decoded to length %d", len(decoded))
|
c.logger.Tracef("frame decoded to length %d", len(decoded))
|
||||||
|
|
||||||
c.framesIn <- decoded
|
c.framesIn <- decoded
|
||||||
|
|
||||||
|
c.logger.Tracef("%d bytes remaining", len(rest))
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.Truncate(0)
|
buffer.Truncate(0)
|
||||||
|
@ -266,9 +291,6 @@ func (c *clientSimulator) readFrames() error {
|
||||||
func (c *clientSimulator) writeFrame(frame []byte) error {
|
func (c *clientSimulator) writeFrame(frame []byte) error {
|
||||||
encoded := cobs.Encode(frame, cobsConfig)
|
encoded := cobs.Encode(frame, cobsConfig)
|
||||||
|
|
||||||
c.lock.Lock()
|
|
||||||
defer c.lock.Unlock()
|
|
||||||
|
|
||||||
if _, err := io.Copy(os.Stdout, bytes.NewBuffer(encoded)); err != nil {
|
if _, err := io.Copy(os.Stdout, bytes.NewBuffer(encoded)); err != nil {
|
||||||
return fmt.Errorf("could not write data: %w", err)
|
return fmt.Errorf("could not write data: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -281,11 +303,15 @@ func (c *clientSimulator) readFromStdin() ([]byte, error) {
|
||||||
|
|
||||||
buf := make([]byte, bufferSize)
|
buf := make([]byte, bufferSize)
|
||||||
|
|
||||||
|
c.logger.Trace("waiting for input")
|
||||||
|
|
||||||
count, err := os.Stdin.Read(buf)
|
count, err := os.Stdin.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("reading input failed: %w", err)
|
return nil, fmt.Errorf("reading input failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.logger.Tracef("read %d bytes from stdin", count)
|
||||||
|
|
||||||
return buf[:count], nil
|
return buf[:count], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,25 +334,6 @@ func (c *clientSimulator) writeCmdAnnouncement() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientSimulator) writeCommandAnnouncement() error {
|
|
||||||
frame, err := c.commandGenerator.CmdAnnouncement()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not get command announcement: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.logger.Trace("writing command announcement")
|
|
||||||
|
|
||||||
if err := c.writeFrame(frame); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.nextState(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientSimulator) writeCommand() error {
|
func (c *clientSimulator) writeCommand() error {
|
||||||
frame, err := c.commandGenerator.CmdData()
|
frame, err := c.commandGenerator.CmdData()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -349,8 +356,8 @@ func (c *clientSimulator) writeCommand() error {
|
||||||
func (c *clientSimulator) handleResponseAnnounce() error {
|
func (c *clientSimulator) handleResponseAnnounce() error {
|
||||||
c.logger.Trace("waiting for response announce")
|
c.logger.Trace("waiting for response announce")
|
||||||
|
|
||||||
select {
|
frame := <-c.framesIn
|
||||||
case frame := <-c.framesIn:
|
|
||||||
if frame == nil {
|
if frame == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -362,7 +369,6 @@ func (c *clientSimulator) handleResponseAnnounce() error {
|
||||||
if err := c.nextState(); err != nil {
|
if err := c.nextState(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -370,8 +376,8 @@ func (c *clientSimulator) handleResponseAnnounce() error {
|
||||||
func (c *clientSimulator) handleResponseData() error {
|
func (c *clientSimulator) handleResponseData() error {
|
||||||
c.logger.Trace("waiting for response data")
|
c.logger.Trace("waiting for response data")
|
||||||
|
|
||||||
select {
|
frame := <-c.framesIn
|
||||||
case frame := <-c.framesIn:
|
|
||||||
if frame == nil {
|
if frame == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -383,7 +389,6 @@ func (c *clientSimulator) handleResponseData() error {
|
||||||
if err := c.nextState(); err != nil {
|
if err := c.nextState(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -412,6 +417,7 @@ func (c *clientSimulator) Run(ctx context.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error from handler loop: %w", err)
|
return fmt.Errorf("error from handler loop: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
if err := c.handleProtocolState(); err != nil {
|
if err := c.handleProtocolState(); err != nil {
|
||||||
|
@ -424,6 +430,9 @@ func (c *clientSimulator) Run(ctx context.Context) error {
|
||||||
func (c *clientSimulator) handleProtocolState() error {
|
func (c *clientSimulator) handleProtocolState() error {
|
||||||
c.logger.Tracef("handling protocol state %s", c.protocolState)
|
c.logger.Tracef("handling protocol state %s", c.protocolState)
|
||||||
|
|
||||||
|
c.lock.Lock()
|
||||||
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
switch c.protocolState {
|
switch c.protocolState {
|
||||||
case cmdAnnounce:
|
case cmdAnnounce:
|
||||||
if err := c.writeCmdAnnouncement(); err != nil {
|
if err := c.writeCmdAnnouncement(); err != nil {
|
||||||
|
@ -462,17 +471,17 @@ func (c *clientSimulator) nextState() error {
|
||||||
func main() {
|
func main() {
|
||||||
logger := logrus.New()
|
logger := logrus.New()
|
||||||
logger.SetOutput(os.Stderr)
|
logger.SetOutput(os.Stderr)
|
||||||
logger.SetLevel(logrus.TraceLevel)
|
logger.SetLevel(logrus.DebugLevel)
|
||||||
|
|
||||||
messages.RegisterGeneratedResolver()
|
messages.RegisterGeneratedResolver()
|
||||||
|
|
||||||
sim := &clientSimulator{
|
sim := &clientSimulator{
|
||||||
commandGenerator: &TestCommandGenerator{
|
commandGenerator: &TestCommandGenerator{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
commands: make(chan *protocol.Command, 0),
|
commands: make(chan *protocol.Command),
|
||||||
},
|
},
|
||||||
logger: logger,
|
logger: logger,
|
||||||
framesIn: make(chan []byte, 0),
|
framesIn: make(chan []byte),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := sim.Run(context.Background())
|
err := sim.Run(context.Background())
|
||||||
|
|
|
@ -35,9 +35,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
commit string
|
commit = "dev"
|
||||||
date string
|
date = "unknown"
|
||||||
version string
|
version = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -4,6 +4,8 @@ go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ThalesIgnite/crypto11 v1.2.5
|
github.com/ThalesIgnite/crypto11 v1.2.5
|
||||||
|
github.com/dave/jennifer v1.4.1
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
github.com/justincpresley/go-cobs v1.2.0
|
github.com/justincpresley/go-cobs v1.2.0
|
||||||
github.com/shamaton/msgpackgen v0.3.0
|
github.com/shamaton/msgpackgen v0.3.0
|
||||||
github.com/sirupsen/logrus v1.9.0
|
github.com/sirupsen/logrus v1.9.0
|
||||||
|
@ -14,7 +16,6 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dave/jennifer v1.4.1 // indirect
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -5,6 +5,8 @@ github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpT
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/justincpresley/go-cobs v1.2.0 h1:dyWszWzXObEv8sxVMJTAIo9XT7HEM10vkAOZq2eVEsQ=
|
github.com/justincpresley/go-cobs v1.2.0 h1:dyWszWzXObEv8sxVMJTAIo9XT7HEM10vkAOZq2eVEsQ=
|
||||||
github.com/justincpresley/go-cobs v1.2.0/go.mod h1:L0d+EbGirv6IzsXNzwULduI2/z3ijkkAmsAuPMpLfqA=
|
github.com/justincpresley/go-cobs v1.2.0/go.mod h1:L0d+EbGirv6IzsXNzwULduI2/z3ijkkAmsAuPMpLfqA=
|
||||||
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
|
|
|
@ -24,8 +24,14 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
// required for msgpackgen
|
||||||
|
_ "github.com/dave/jennifer"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CommandCode int8
|
type CommandCode int8
|
||||||
|
@ -72,33 +78,48 @@ func (c ResponseCode) String() string {
|
||||||
|
|
||||||
type CommandAnnounce struct {
|
type CommandAnnounce struct {
|
||||||
Code CommandCode `msgpack:"code"`
|
Code CommandCode `msgpack:"code"`
|
||||||
|
ID string `msgpack:"id"`
|
||||||
Created time.Time `msgpack:"created"`
|
Created time.Time `msgpack:"created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CommandAnnounce) String() string {
|
func (r *CommandAnnounce) String() string {
|
||||||
return fmt.Sprintf("CommandAnnounce[code=%s, created=%s]", r.Code, r.Created)
|
return fmt.Sprintf("code=%s, id=%s, created=%s", r.Code, r.ID, r.Created.Format(time.RFC3339))
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseAnnounce struct {
|
type ResponseAnnounce struct {
|
||||||
Code ResponseCode `msgpack:"code"`
|
Code ResponseCode `msgpack:"code"`
|
||||||
Created time.Time `msgpack:"created"`
|
Created time.Time `msgpack:"created"`
|
||||||
|
ID string `msgpack:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ResponseAnnounce) String() string {
|
func (r *ResponseAnnounce) String() string {
|
||||||
return fmt.Sprintf("ResponseAnnounce[code=%s, created=%s]", r.Code, r.Created)
|
return fmt.Sprintf("code=%s, id=%s, created=%s", r.Code, r.ID, r.Created.Format(time.RFC3339))
|
||||||
}
|
}
|
||||||
|
|
||||||
type FetchCRLCommand struct {
|
type FetchCRLCommand struct {
|
||||||
IssuerID string `msgpack:"issuer_id"`
|
IssuerID string `msgpack:"issuer_id"`
|
||||||
LastKnownHash struct {
|
LastKnownID *big.Int `msgpack:"last_known_id"`
|
||||||
Algorithm string `msgpack:"algorithm"`
|
}
|
||||||
Value string `msgpack:"value"`
|
|
||||||
} `msgpack:"last_known_hash"` // optional last known hash in format
|
func (f *FetchCRLCommand) String() string {
|
||||||
|
builder := &strings.Builder{}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(builder, "issuerId='%s'", f.IssuerID)
|
||||||
|
|
||||||
|
if f.LastKnownID != nil {
|
||||||
|
_, _ = fmt.Fprintf(builder, ", lastKnownId=%s", f.LastKnownID.Text(16))
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type HealthCommand struct {
|
type HealthCommand struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *HealthCommand) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type HealthInfo struct {
|
type HealthInfo struct {
|
||||||
Source string
|
Source string
|
||||||
Healthy bool
|
Healthy bool
|
||||||
|
@ -141,6 +162,7 @@ type FetchCRLResponse struct {
|
||||||
IssuerID string `msgpack:"issuer_id"`
|
IssuerID string `msgpack:"issuer_id"`
|
||||||
IsDelta bool `msgpack:"is_delta"`
|
IsDelta bool `msgpack:"is_delta"`
|
||||||
CRLData []byte `msgpack:"crl_data"`
|
CRLData []byte `msgpack:"crl_data"`
|
||||||
|
CRLNumber *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FetchCRLResponse) String() string {
|
func (r *FetchCRLResponse) String() string {
|
||||||
|
@ -151,12 +173,18 @@ func (r *FetchCRLResponse) String() string {
|
||||||
if r.IsDelta {
|
if r.IsDelta {
|
||||||
_, _ = fmt.Fprint(builder, ", delta CRL data not shown")
|
_, _ = fmt.Fprint(builder, ", delta CRL data not shown")
|
||||||
} else {
|
} else {
|
||||||
revlist, err := x509.ParseRevocationList(r.CRLData)
|
revocationList, err := x509.ParseRevocationList(r.CRLData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = fmt.Fprintf(builder, ", could not parse CRL: %s", err.Error())
|
_, _ = fmt.Fprintf(builder, ", could not parse CRL: %s", err.Error())
|
||||||
} else {
|
} else {
|
||||||
_, _ = fmt.Fprintf(builder, ", CRL info: issuer=%s, number=%s, next update=%s, revoked certificates=%d",
|
_, _ = fmt.Fprintf(
|
||||||
revlist.Issuer, revlist.Number, revlist.NextUpdate, len(revlist.RevokedCertificates))
|
builder,
|
||||||
|
", CRL info: issuer=%s, number=%s, next update=%s, revoked certificates=%d",
|
||||||
|
revocationList.Issuer,
|
||||||
|
revocationList.Number,
|
||||||
|
revocationList.NextUpdate,
|
||||||
|
len(revocationList.RevokedCertificates),
|
||||||
|
)
|
||||||
_, _ = builder.WriteString(", CRL data:\n")
|
_, _ = builder.WriteString(", CRL data:\n")
|
||||||
_ = pem.Encode(builder, &pem.Block{
|
_ = pem.Encode(builder, &pem.Block{
|
||||||
Type: "CERTIFICATE REVOCATION LIST",
|
Type: "CERTIFICATE REVOCATION LIST",
|
||||||
|
@ -172,10 +200,19 @@ type ErrorResponse struct {
|
||||||
Message string `msgpack:"message"`
|
Message string `msgpack:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildCommandAnnounce(code CommandCode) *CommandAnnounce {
|
func (e *ErrorResponse) String() string {
|
||||||
return &CommandAnnounce{Code: code, Created: time.Now().UTC()}
|
return fmt.Sprintf("message=%s", e.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildResponseAnnounce(code ResponseCode) *ResponseAnnounce {
|
func BuildCommandAnnounce(code CommandCode) (*CommandAnnounce, error) {
|
||||||
return &ResponseAnnounce{Code: code, Created: time.Now().UTC()}
|
commandID, err := uuid.NewUUID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not build command id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CommandAnnounce{Code: code, ID: commandID.String(), Created: time.Now().UTC()}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildResponseAnnounce(code ResponseCode, commandID string) *ResponseAnnounce {
|
||||||
|
return &ResponseAnnounce{Code: code, ID: commandID, Created: time.Now().UTC()}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,36 +116,6 @@ func ___encodeAsArray(i interface{}) ([]byte, error) {
|
||||||
return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset)
|
return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset)
|
||||||
}
|
}
|
||||||
return b, err
|
return b, err
|
||||||
case FetchCRLResponse:
|
|
||||||
encoder := enc.NewEncoder()
|
|
||||||
size, err := ___calcArraySizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
encoder.MakeBytes(size)
|
|
||||||
b, offset, err := ___encodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if size != offset {
|
|
||||||
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
|
|
||||||
}
|
|
||||||
return b, err
|
|
||||||
case *FetchCRLResponse:
|
|
||||||
encoder := enc.NewEncoder()
|
|
||||||
size, err := ___calcArraySizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
encoder.MakeBytes(size)
|
|
||||||
b, offset, err := ___encodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if size != offset {
|
|
||||||
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
|
|
||||||
}
|
|
||||||
return b, err
|
|
||||||
case ErrorResponse:
|
case ErrorResponse:
|
||||||
encoder := enc.NewEncoder()
|
encoder := enc.NewEncoder()
|
||||||
size, err := ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
|
size, err := ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
|
||||||
|
@ -273,36 +243,6 @@ func ___encodeAsMap(i interface{}) ([]byte, error) {
|
||||||
return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset)
|
return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset)
|
||||||
}
|
}
|
||||||
return b, err
|
return b, err
|
||||||
case FetchCRLResponse:
|
|
||||||
encoder := enc.NewEncoder()
|
|
||||||
size, err := ___calcMapSizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
encoder.MakeBytes(size)
|
|
||||||
b, offset, err := ___encodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if size != offset {
|
|
||||||
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
|
|
||||||
}
|
|
||||||
return b, err
|
|
||||||
case *FetchCRLResponse:
|
|
||||||
encoder := enc.NewEncoder()
|
|
||||||
size, err := ___calcMapSizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
encoder.MakeBytes(size)
|
|
||||||
b, offset, err := ___encodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if size != offset {
|
|
||||||
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
|
|
||||||
}
|
|
||||||
return b, err
|
|
||||||
case ErrorResponse:
|
case ErrorResponse:
|
||||||
encoder := enc.NewEncoder()
|
encoder := enc.NewEncoder()
|
||||||
size, err := ___calcMapSizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
|
size, err := ___calcMapSizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
|
||||||
|
@ -391,20 +331,6 @@ func ___decodeAsArray(data []byte, i interface{}) (bool, error) {
|
||||||
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
||||||
}
|
}
|
||||||
return true, err
|
return true, err
|
||||||
case *FetchCRLResponse:
|
|
||||||
decoder := dec.NewDecoder(data)
|
|
||||||
offset, err := ___decodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
|
|
||||||
if err == nil && offset != decoder.Len() {
|
|
||||||
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
|
||||||
}
|
|
||||||
return true, err
|
|
||||||
case **FetchCRLResponse:
|
|
||||||
decoder := dec.NewDecoder(data)
|
|
||||||
offset, err := ___decodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0)
|
|
||||||
if err == nil && offset != decoder.Len() {
|
|
||||||
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
|
||||||
}
|
|
||||||
return true, err
|
|
||||||
case *ErrorResponse:
|
case *ErrorResponse:
|
||||||
decoder := dec.NewDecoder(data)
|
decoder := dec.NewDecoder(data)
|
||||||
offset, err := ___decodeArrayErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
|
offset, err := ___decodeArrayErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
|
||||||
|
@ -468,20 +394,6 @@ func ___decodeAsMap(data []byte, i interface{}) (bool, error) {
|
||||||
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
||||||
}
|
}
|
||||||
return true, err
|
return true, err
|
||||||
case *FetchCRLResponse:
|
|
||||||
decoder := dec.NewDecoder(data)
|
|
||||||
offset, err := ___decodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
|
|
||||||
if err == nil && offset != decoder.Len() {
|
|
||||||
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
|
||||||
}
|
|
||||||
return true, err
|
|
||||||
case **FetchCRLResponse:
|
|
||||||
decoder := dec.NewDecoder(data)
|
|
||||||
offset, err := ___decodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0)
|
|
||||||
if err == nil && offset != decoder.Len() {
|
|
||||||
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
|
|
||||||
}
|
|
||||||
return true, err
|
|
||||||
case *ErrorResponse:
|
case *ErrorResponse:
|
||||||
decoder := dec.NewDecoder(data)
|
decoder := dec.NewDecoder(data)
|
||||||
offset, err := ___decodeMapErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
|
offset, err := ___decodeMapErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
|
||||||
|
@ -1057,217 +969,6 @@ func ___decodeMapHealthResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f
|
||||||
return offset, err
|
return offset, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
|
|
||||||
func ___calcArraySizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder) (int, error) {
|
|
||||||
size := 0
|
|
||||||
size += encoder.CalcStructHeaderFix(3)
|
|
||||||
size += encoder.CalcString(v.IssuerID)
|
|
||||||
size += encoder.CalcBool(v.IsDelta)
|
|
||||||
if v.CRLData != nil {
|
|
||||||
s, err := encoder.CalcSliceLength(len(v.CRLData), true)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
size += s
|
|
||||||
for _, vv := range v.CRLData {
|
|
||||||
size += encoder.CalcByte(vv)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
size += encoder.CalcNil()
|
|
||||||
}
|
|
||||||
return size, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
|
|
||||||
func ___calcMapSizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder) (int, error) {
|
|
||||||
size := 0
|
|
||||||
size += encoder.CalcStructHeaderFix(3)
|
|
||||||
size += encoder.CalcStringFix(9)
|
|
||||||
size += encoder.CalcString(v.IssuerID)
|
|
||||||
size += encoder.CalcStringFix(8)
|
|
||||||
size += encoder.CalcBool(v.IsDelta)
|
|
||||||
size += encoder.CalcStringFix(8)
|
|
||||||
if v.CRLData != nil {
|
|
||||||
s, err := encoder.CalcSliceLength(len(v.CRLData), true)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
size += s
|
|
||||||
for _, vv := range v.CRLData {
|
|
||||||
size += encoder.CalcByte(vv)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
size += encoder.CalcNil()
|
|
||||||
}
|
|
||||||
return size, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// encode from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
|
|
||||||
func ___encodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder, offset int) ([]byte, int, error) {
|
|
||||||
var err error
|
|
||||||
offset = encoder.WriteStructHeaderFixAsArray(3, offset)
|
|
||||||
offset = encoder.WriteString(v.IssuerID, offset)
|
|
||||||
offset = encoder.WriteBool(v.IsDelta, offset)
|
|
||||||
if v.CRLData != nil {
|
|
||||||
offset = encoder.WriteSliceLength(len(v.CRLData), offset, true)
|
|
||||||
for _, vv := range v.CRLData {
|
|
||||||
offset = encoder.WriteByte(vv, offset)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
offset = encoder.WriteNil(offset)
|
|
||||||
}
|
|
||||||
return encoder.EncodedBytes(), offset, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// encode from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
|
|
||||||
func ___encodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder, offset int) ([]byte, int, error) {
|
|
||||||
var err error
|
|
||||||
offset = encoder.WriteStructHeaderFixAsMap(3, offset)
|
|
||||||
offset = encoder.WriteStringFix("issuer_id", 9, offset)
|
|
||||||
offset = encoder.WriteString(v.IssuerID, offset)
|
|
||||||
offset = encoder.WriteStringFix("is_delta", 8, offset)
|
|
||||||
offset = encoder.WriteBool(v.IsDelta, offset)
|
|
||||||
offset = encoder.WriteStringFix("crl_data", 8, offset)
|
|
||||||
if v.CRLData != nil {
|
|
||||||
offset = encoder.WriteSliceLength(len(v.CRLData), offset, true)
|
|
||||||
for _, vv := range v.CRLData {
|
|
||||||
offset = encoder.WriteByte(vv, offset)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
offset = encoder.WriteNil(offset)
|
|
||||||
}
|
|
||||||
return encoder.EncodedBytes(), offset, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// decode to git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
|
|
||||||
func ___decodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *FetchCRLResponse, decoder *dec.Decoder, offset int) (int, error) {
|
|
||||||
offset, err := decoder.CheckStructHeader(3, offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
{
|
|
||||||
var vv string
|
|
||||||
vv, offset, err = decoder.AsString(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
v.IssuerID = vv
|
|
||||||
}
|
|
||||||
{
|
|
||||||
var vv bool
|
|
||||||
vv, offset, err = decoder.AsBool(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
v.IsDelta = vv
|
|
||||||
}
|
|
||||||
if !decoder.IsCodeNil(offset) {
|
|
||||||
var vv []byte
|
|
||||||
var vvl int
|
|
||||||
vvl, offset, err = decoder.SliceLength(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
vv = make([]byte, vvl)
|
|
||||||
for vvi := range vv {
|
|
||||||
var vvv byte
|
|
||||||
vvv, offset, err = decoder.AsByte(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
vv[vvi] = vvv
|
|
||||||
}
|
|
||||||
v.CRLData = vv
|
|
||||||
} else {
|
|
||||||
offset++
|
|
||||||
}
|
|
||||||
return offset, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// decode to git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
|
|
||||||
func ___decodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *FetchCRLResponse, decoder *dec.Decoder, offset int) (int, error) {
|
|
||||||
keys := [][]byte{
|
|
||||||
{uint8(0x69), uint8(0x73), uint8(0x73), uint8(0x75), uint8(0x65), uint8(0x72), uint8(0x5f), uint8(0x69), uint8(0x64)}, // issuer_id
|
|
||||||
{uint8(0x69), uint8(0x73), uint8(0x5f), uint8(0x64), uint8(0x65), uint8(0x6c), uint8(0x74), uint8(0x61)}, // is_delta
|
|
||||||
{uint8(0x63), uint8(0x72), uint8(0x6c), uint8(0x5f), uint8(0x64), uint8(0x61), uint8(0x74), uint8(0x61)}, // crl_data
|
|
||||||
}
|
|
||||||
offset, err := decoder.CheckStructHeader(3, offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
count := 0
|
|
||||||
for count < 3 {
|
|
||||||
var dataKey []byte
|
|
||||||
dataKey, offset, err = decoder.AsStringBytes(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
fieldIndex := -1
|
|
||||||
for i, key := range keys {
|
|
||||||
if len(dataKey) != len(key) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fieldIndex = i
|
|
||||||
for dataKeyIndex := range dataKey {
|
|
||||||
if dataKey[dataKeyIndex] != key[dataKeyIndex] {
|
|
||||||
fieldIndex = -1
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fieldIndex >= 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch fieldIndex {
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
var vv string
|
|
||||||
vv, offset, err = decoder.AsString(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
v.IssuerID = vv
|
|
||||||
}
|
|
||||||
count++
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
var vv bool
|
|
||||||
vv, offset, err = decoder.AsBool(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
v.IsDelta = vv
|
|
||||||
}
|
|
||||||
count++
|
|
||||||
case 2:
|
|
||||||
if !decoder.IsCodeNil(offset) {
|
|
||||||
var vv []byte
|
|
||||||
var vvl int
|
|
||||||
vvl, offset, err = decoder.SliceLength(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
vv = make([]byte, vvl)
|
|
||||||
for vvi := range vv {
|
|
||||||
var vvv byte
|
|
||||||
vvv, offset, err = decoder.AsByte(offset)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
vv[vvi] = vvv
|
|
||||||
}
|
|
||||||
v.CRLData = vv
|
|
||||||
} else {
|
|
||||||
offset++
|
|
||||||
}
|
|
||||||
count++
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("unknown key[%s] found", string(dataKey))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.ErrorResponse
|
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.ErrorResponse
|
||||||
func ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v ErrorResponse, encoder *enc.Encoder) (int, error) {
|
func ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v ErrorResponse, encoder *enc.Encoder) (int, error) {
|
||||||
size := 0
|
size := 0
|
||||||
|
|
282
pkg/protocol/msgpack.go
Normal file
282
pkg/protocol/msgpack.go
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 CAcert Inc.
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/shamaton/msgpackgen/msgpack"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"git.cacert.org/cacert-gosigner/pkg/health"
|
||||||
|
"git.cacert.org/cacert-gosigner/pkg/messages"
|
||||||
|
"git.cacert.org/cacert-gosigner/pkg/x509/revoking"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MsgPackHandler is a Handler implementation for the msgpack serialization format.
|
||||||
|
type MsgPackHandler struct {
|
||||||
|
logger *logrus.Logger
|
||||||
|
healthHandler *health.Handler
|
||||||
|
fetchCRLHandler *revoking.FetchCRLHandler
|
||||||
|
currentCommand *Command
|
||||||
|
currentResponse *Response
|
||||||
|
lock sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) HandleCommandAnnounce(frame []byte) error {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
|
var ann messages.CommandAnnounce
|
||||||
|
|
||||||
|
if err := msgpack.Unmarshal(frame, &ann); err != nil {
|
||||||
|
return fmt.Errorf("could not unmarshal command announcement: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.logger.WithField("announcement", &ann).Info("received command announcement")
|
||||||
|
|
||||||
|
m.currentCommand = &Command{Announce: &ann}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) HandleCommand(frame []byte) error {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
|
err := m.parseCommand(frame)
|
||||||
|
if err != nil {
|
||||||
|
m.currentResponse = m.buildErrorResponse(err.Error())
|
||||||
|
|
||||||
|
m.logCommandResponse()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.handleCommand()
|
||||||
|
if err != nil {
|
||||||
|
m.logger.WithError(err).Error("command handling failed")
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m.logCommandResponse()
|
||||||
|
|
||||||
|
m.currentCommand = nil
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) logCommandResponse() {
|
||||||
|
m.logger.WithField("command", m.currentCommand.Announce).Info("handled command")
|
||||||
|
m.logger.WithField(
|
||||||
|
"command",
|
||||||
|
m.currentCommand,
|
||||||
|
).WithField(
|
||||||
|
"response",
|
||||||
|
m.currentResponse,
|
||||||
|
).Debug("command and response")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) ResponseAnnounce() ([]byte, error) {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
|
announceData, err := msgpack.Marshal(m.currentResponse.Announce)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not marshal response announcement: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.logger.WithField("announcement", m.currentResponse.Announce).Debug("write response announcement")
|
||||||
|
|
||||||
|
return announceData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) ResponseData() ([]byte, error) {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
|
responseData, err := msgpack.Marshal(m.currentResponse.Response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not marshal response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.logger.WithField("response", m.currentResponse.Response).Debug("write response")
|
||||||
|
|
||||||
|
return responseData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) parseHealthCommand(frame []byte) error {
|
||||||
|
var command messages.HealthCommand
|
||||||
|
|
||||||
|
if err := msgpack.Unmarshal(frame, &command); err != nil {
|
||||||
|
m.logger.WithError(err).Error("unmarshal failed")
|
||||||
|
|
||||||
|
return errors.New("could not unmarshal health command")
|
||||||
|
}
|
||||||
|
|
||||||
|
m.currentCommand.Command = &command
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) parseFetchCRLCommand(frame []byte) error {
|
||||||
|
var command messages.FetchCRLCommand
|
||||||
|
|
||||||
|
if err := msgpack.Unmarshal(frame, &command); err != nil {
|
||||||
|
m.logger.WithError(err).Error("unmarshal failed")
|
||||||
|
|
||||||
|
return errors.New("could not unmarshal fetch crl command")
|
||||||
|
}
|
||||||
|
|
||||||
|
m.currentCommand.Command = &command
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) currentID() string {
|
||||||
|
return m.currentCommand.Announce.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) handleCommand() error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
responseData interface{}
|
||||||
|
responseCode messages.ResponseCode
|
||||||
|
)
|
||||||
|
|
||||||
|
switch m.currentCommand.Command.(type) {
|
||||||
|
case *messages.HealthCommand:
|
||||||
|
response, err := m.handleHealthCommand()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
responseCode, responseData = messages.RespHealth, response
|
||||||
|
case *messages.FetchCRLCommand:
|
||||||
|
response, err := m.handleFetchCRLCommand()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
responseCode, responseData = messages.RespFetchCRL, response
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unhandled command %s", m.currentCommand.Announce)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error from command handler: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.currentResponse = &Response{
|
||||||
|
Announce: messages.BuildResponseAnnounce(responseCode, m.currentID()),
|
||||||
|
Response: responseData,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) buildErrorResponse(errMsg string) *Response {
|
||||||
|
return &Response{
|
||||||
|
Announce: messages.BuildResponseAnnounce(messages.RespError, m.currentID()),
|
||||||
|
Response: &messages.ErrorResponse{Message: errMsg},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) parseCommand(frame []byte) error {
|
||||||
|
switch m.currentCommand.Announce.Code {
|
||||||
|
case messages.CmdHealth:
|
||||||
|
return m.parseHealthCommand(frame)
|
||||||
|
case messages.CmdFetchCRL:
|
||||||
|
return m.parseFetchCRLCommand(frame)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unhandled command code %s", m.currentCommand.Announce.Code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) handleHealthCommand() (*messages.HealthResponse, error) {
|
||||||
|
res, err := m.healthHandler.CheckHealth()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not check health: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &messages.HealthResponse{
|
||||||
|
Version: res.Version,
|
||||||
|
Healthy: res.Healthy,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, info := range res.Info {
|
||||||
|
response.Info = append(response.Info, &messages.HealthInfo{
|
||||||
|
Source: info.Source,
|
||||||
|
Healthy: info.Healthy,
|
||||||
|
MoreInfo: info.MoreInfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgPackHandler) handleFetchCRLCommand() (*messages.FetchCRLResponse, error) {
|
||||||
|
fetchCRLPayload, ok := m.currentCommand.Command.(*messages.FetchCRLCommand)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("could not use payload as FetchCRLPayload")
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.fetchCRLHandler.FetchCRL(fetchCRLPayload.IssuerID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not fetch CRL: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &messages.FetchCRLResponse{
|
||||||
|
IsDelta: false,
|
||||||
|
CRLNumber: res.Number,
|
||||||
|
CRLData: res.CRLData,
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(logger *logrus.Logger, handlers ...RegisterHandler) (Handler, error) {
|
||||||
|
messages.RegisterGeneratedResolver()
|
||||||
|
|
||||||
|
h := &MsgPackHandler{
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, reg := range handlers {
|
||||||
|
reg(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterHandler func(handler *MsgPackHandler)
|
||||||
|
|
||||||
|
func RegisterHealthHandler(healthHandler *health.Handler) func(*MsgPackHandler) {
|
||||||
|
return func(h *MsgPackHandler) {
|
||||||
|
h.healthHandler = healthHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterFetchCRLHandler(fetchCRLHandler *revoking.FetchCRLHandler) func(handler *MsgPackHandler) {
|
||||||
|
return func(h *MsgPackHandler) {
|
||||||
|
h.fetchCRLHandler = fetchCRLHandler
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,250 +19,39 @@ limitations under the License.
|
||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/shamaton/msgpackgen/msgpack"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"git.cacert.org/cacert-gosigner/pkg/x509/revoking"
|
|
||||||
|
|
||||||
"git.cacert.org/cacert-gosigner/pkg/health"
|
|
||||||
"git.cacert.org/cacert-gosigner/pkg/messages"
|
"git.cacert.org/cacert-gosigner/pkg/messages"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const CobsDelimiter = 0x00
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
Announce *messages.CommandAnnounce
|
Announce *messages.CommandAnnounce
|
||||||
Command interface{}
|
Command interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) String() string {
|
||||||
|
return fmt.Sprintf("Cmd[announce={%s}, data={%s}]", c.Announce, c.Command)
|
||||||
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Announce *messages.ResponseAnnounce
|
Announce *messages.ResponseAnnounce
|
||||||
Response interface{}
|
Response interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Response) String() string {
|
func (r *Response) String() string {
|
||||||
return fmt.Sprintf("Response[Code=%s] created=%s data=%s", r.Announce.Code, r.Announce.Created, r.Response)
|
return fmt.Sprintf("Rsp[announce={%s}, data={%s}]", r.Announce, r.Response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handler is responsible for parsing incoming frames and calling commands
|
// Handler is responsible for parsing incoming frames and calling commands
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
|
// HandleCommandAnnounce handles the initial announcement of a command.
|
||||||
HandleCommandAnnounce([]byte) error
|
HandleCommandAnnounce([]byte) error
|
||||||
|
// HandleCommand handles the command data.
|
||||||
HandleCommand([]byte) error
|
HandleCommand([]byte) error
|
||||||
|
// ResponseAnnounce generates the announcement for a response.
|
||||||
ResponseAnnounce() ([]byte, error)
|
ResponseAnnounce() ([]byte, error)
|
||||||
|
// ResponseData generates the response data.
|
||||||
ResponseData() ([]byte, error)
|
ResponseData() ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgPackHandler struct {
|
|
||||||
logger *logrus.Logger
|
|
||||||
healthHandler *health.Handler
|
|
||||||
fetchCRLHandler *revoking.FetchCRLHandler
|
|
||||||
currentCommand *Command
|
|
||||||
currentResponse *Response
|
|
||||||
lock sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgPackHandler) HandleCommandAnnounce(frame []byte) error {
|
|
||||||
m.lock.Lock()
|
|
||||||
defer m.lock.Unlock()
|
|
||||||
|
|
||||||
var ann messages.CommandAnnounce
|
|
||||||
|
|
||||||
if err := msgpack.Unmarshal(frame, &ann); err != nil {
|
|
||||||
return fmt.Errorf("could not unmarshal command announcement: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.logger.WithField("announcement", &ann).Info("received command announcement")
|
|
||||||
|
|
||||||
m.currentCommand = &Command{Announce: &ann}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgPackHandler) HandleCommand(frame []byte) error {
|
|
||||||
m.lock.Lock()
|
|
||||||
defer m.lock.Unlock()
|
|
||||||
|
|
||||||
var clientError error
|
|
||||||
|
|
||||||
switch m.currentCommand.Announce.Code {
|
|
||||||
case messages.CmdHealth:
|
|
||||||
// health has no payload, ignore the frame
|
|
||||||
response, err := m.handleCommand()
|
|
||||||
if err != nil {
|
|
||||||
m.logger.WithError(err).Error("health handling failed")
|
|
||||||
|
|
||||||
clientError = errors.New("could not handle request")
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
m.currentResponse = response
|
|
||||||
case messages.CmdFetchCRL:
|
|
||||||
var command messages.FetchCRLCommand
|
|
||||||
|
|
||||||
if err := msgpack.Unmarshal(frame, &command); err != nil {
|
|
||||||
m.logger.WithError(err).Error("unmarshal failed")
|
|
||||||
|
|
||||||
clientError = errors.New("could not unmarshal fetch crl command")
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
m.currentCommand.Command = command
|
|
||||||
|
|
||||||
response, err := m.handleCommand()
|
|
||||||
if err != nil {
|
|
||||||
m.logger.WithError(err).Error("fetch CRL handling failed")
|
|
||||||
|
|
||||||
clientError = errors.New("could not handle request")
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
m.currentResponse = response
|
|
||||||
}
|
|
||||||
|
|
||||||
if clientError != nil {
|
|
||||||
m.currentResponse = buildErrorResponse(clientError.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
m.logger.WithField(
|
|
||||||
"command",
|
|
||||||
m.currentCommand,
|
|
||||||
).WithField(
|
|
||||||
"response",
|
|
||||||
m.currentResponse,
|
|
||||||
).Info("handled command")
|
|
||||||
|
|
||||||
m.currentCommand = nil
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgPackHandler) ResponseAnnounce() ([]byte, error) {
|
|
||||||
m.lock.Lock()
|
|
||||||
defer m.lock.Unlock()
|
|
||||||
|
|
||||||
announceData, err := msgpack.Marshal(m.currentResponse.Announce)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not marshal response announcement: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.logger.WithField("announcement", &m.currentResponse.Announce).Info("write response announcement")
|
|
||||||
|
|
||||||
return announceData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgPackHandler) ResponseData() ([]byte, error) {
|
|
||||||
m.lock.Lock()
|
|
||||||
defer m.lock.Unlock()
|
|
||||||
|
|
||||||
responseData, err := msgpack.Marshal(m.currentResponse.Response)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not marshal response: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.logger.WithField("response", &m.currentResponse.Response).Info("write response")
|
|
||||||
|
|
||||||
return responseData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgPackHandler) handleCommand() (*Response, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
responseData interface{}
|
|
||||||
responseCode messages.ResponseCode
|
|
||||||
)
|
|
||||||
|
|
||||||
switch m.currentCommand.Announce.Code {
|
|
||||||
case messages.CmdHealth:
|
|
||||||
var res *health.Result
|
|
||||||
|
|
||||||
res, err = m.healthHandler.CheckHealth()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &messages.HealthResponse{
|
|
||||||
Version: res.Version,
|
|
||||||
Healthy: res.Healthy,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, info := range res.Info {
|
|
||||||
response.Info = append(response.Info, &messages.HealthInfo{
|
|
||||||
Source: info.Source,
|
|
||||||
Healthy: info.Healthy,
|
|
||||||
MoreInfo: info.MoreInfo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
responseCode, responseData = messages.RespHealth, response
|
|
||||||
case messages.CmdFetchCRL:
|
|
||||||
var res *revoking.Result
|
|
||||||
|
|
||||||
fetchCRLPayload, ok := m.currentCommand.Command.(messages.FetchCRLCommand)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("could not use payload as FetchCRLPayload")
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err = m.fetchCRLHandler.FetchCRL(fetchCRLPayload.IssuerID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &messages.FetchCRLResponse{
|
|
||||||
IsDelta: false,
|
|
||||||
CRLData: res.Data,
|
|
||||||
}
|
|
||||||
|
|
||||||
responseCode, responseData = messages.RespFetchCRL, response
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unhandled command %s", m.currentCommand.Announce)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error from command handler: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Response{
|
|
||||||
Announce: messages.BuildResponseAnnounce(responseCode),
|
|
||||||
Response: responseData,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildErrorResponse(errMsg string) *Response {
|
|
||||||
return &Response{
|
|
||||||
Announce: messages.BuildResponseAnnounce(messages.RespError),
|
|
||||||
Response: &messages.ErrorResponse{Message: errMsg},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(logger *logrus.Logger, handlers ...RegisterHandler) (Handler, error) {
|
|
||||||
messages.RegisterGeneratedResolver()
|
|
||||||
|
|
||||||
h := &MsgPackHandler{
|
|
||||||
logger: logger,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, reg := range handlers {
|
|
||||||
reg(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegisterHandler func(handler *MsgPackHandler)
|
|
||||||
|
|
||||||
func RegisterHealthHandler(healthHandler *health.Handler) func(*MsgPackHandler) {
|
|
||||||
return func(h *MsgPackHandler) {
|
|
||||||
h.healthHandler = healthHandler
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterFetchCRLHandler(fetchCRLHandler *revoking.FetchCRLHandler) func(handler *MsgPackHandler) {
|
|
||||||
return func(h *MsgPackHandler) {
|
|
||||||
h.fetchCRLHandler = fetchCRLHandler
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ func (h *Handler) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var cobsConfig = cobs.Config{SpecialByte: 0x00, Delimiter: true, EndingSave: true}
|
var cobsConfig = cobs.Config{SpecialByte: protocol.CobsDelimiter, Delimiter: true, EndingSave: true}
|
||||||
|
|
||||||
func (h *Handler) Run(ctx context.Context) error {
|
func (h *Handler) Run(ctx context.Context) error {
|
||||||
h.protocolState = cmdAnnounce
|
h.protocolState = cmdAnnounce
|
||||||
|
@ -133,7 +133,9 @@ func (h *Handler) readFrames() error {
|
||||||
)
|
)
|
||||||
|
|
||||||
var frame []byte
|
var frame []byte
|
||||||
|
|
||||||
buffer := &bytes.Buffer{}
|
buffer := &bytes.Buffer{}
|
||||||
|
|
||||||
delimiter := []byte{cobsConfig.SpecialByte}
|
delimiter := []byte{cobsConfig.SpecialByte}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -212,6 +214,9 @@ func (h *Handler) nextState() error {
|
||||||
func (h *Handler) handleProtocolState() error {
|
func (h *Handler) handleProtocolState() error {
|
||||||
h.logger.Tracef("handling protocol state %s", h.protocolState)
|
h.logger.Tracef("handling protocol state %s", h.protocolState)
|
||||||
|
|
||||||
|
h.lock.Lock()
|
||||||
|
defer h.lock.Unlock()
|
||||||
|
|
||||||
switch h.protocolState {
|
switch h.protocolState {
|
||||||
case cmdAnnounce:
|
case cmdAnnounce:
|
||||||
if err := h.handleCmdAnnounce(); err != nil {
|
if err := h.handleCmdAnnounce(); err != nil {
|
||||||
|
@ -237,9 +242,6 @@ func (h *Handler) handleProtocolState() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) writeToPort(data []byte) error {
|
func (h *Handler) writeToPort(data []byte) error {
|
||||||
h.lock.Lock()
|
|
||||||
defer h.lock.Unlock()
|
|
||||||
|
|
||||||
reader := bytes.NewReader(data)
|
reader := bytes.NewReader(data)
|
||||||
|
|
||||||
n, err := io.Copy(h.port, reader)
|
n, err := io.Copy(h.port, reader)
|
||||||
|
@ -249,10 +251,6 @@ func (h *Handler) writeToPort(data []byte) error {
|
||||||
|
|
||||||
h.logger.Tracef("wrote %d bytes", n)
|
h.logger.Tracef("wrote %d bytes", n)
|
||||||
|
|
||||||
if err := h.port.Flush(); err != nil {
|
|
||||||
return fmt.Errorf("could not flush data: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,8 +270,7 @@ func (h *Handler) readFromPort() ([]byte, error) {
|
||||||
func (h *Handler) handleCmdAnnounce() error {
|
func (h *Handler) handleCmdAnnounce() error {
|
||||||
h.logger.Trace("waiting for command announce")
|
h.logger.Trace("waiting for command announce")
|
||||||
|
|
||||||
select {
|
frame := <-h.framesIn
|
||||||
case frame := <-h.framesIn:
|
|
||||||
if frame == nil {
|
if frame == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -285,7 +282,6 @@ func (h *Handler) handleCmdAnnounce() error {
|
||||||
if err := h.nextState(); err != nil {
|
if err := h.nextState(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -293,8 +289,7 @@ func (h *Handler) handleCmdAnnounce() error {
|
||||||
func (h *Handler) handleCmdData() error {
|
func (h *Handler) handleCmdData() error {
|
||||||
h.logger.Trace("waiting for command data")
|
h.logger.Trace("waiting for command data")
|
||||||
|
|
||||||
select {
|
frame := <-h.framesIn
|
||||||
case frame := <-h.framesIn:
|
|
||||||
|
|
||||||
if frame == nil {
|
if frame == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -307,7 +302,6 @@ func (h *Handler) handleCmdData() error {
|
||||||
if err := h.nextState(); err != nil {
|
if err := h.nextState(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -318,8 +312,6 @@ func (h *Handler) handleRespAnnounce() error {
|
||||||
return fmt.Errorf("could not get response announcement: %w", err)
|
return fmt.Errorf("could not get response announcement: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.logger.Trace("writing response announce")
|
|
||||||
|
|
||||||
if err := h.writeFrame(frame); err != nil {
|
if err := h.writeFrame(frame); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -337,8 +329,6 @@ func (h *Handler) handleRespData() error {
|
||||||
return fmt.Errorf("could not get response data: %w", err)
|
return fmt.Errorf("could not get response data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.logger.Trace("writing response data")
|
|
||||||
|
|
||||||
if err := h.writeFrame(frame); err != nil {
|
if err := h.writeFrame(frame); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -354,7 +344,7 @@ func New(cfg *config.Serial, logger *logrus.Logger, protocolHandler protocol.Han
|
||||||
h := &Handler{
|
h := &Handler{
|
||||||
protocolHandler: protocolHandler,
|
protocolHandler: protocolHandler,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
framesIn: make(chan []byte, 0),
|
framesIn: make(chan []byte),
|
||||||
}
|
}
|
||||||
h.config = &serial.Config{Name: cfg.Device, Baud: cfg.Baud, ReadTimeout: cfg.Timeout}
|
h.config = &serial.Config{Name: cfg.Device, Baud: cfg.Baud, ReadTimeout: cfg.Timeout}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@ func NewRevokeCertificate(serialNumber *big.Int, reason CRLReason) *RevokeCertif
|
||||||
|
|
||||||
type CRLInformation struct {
|
type CRLInformation struct {
|
||||||
CRL []byte // DER encoded CRL
|
CRL []byte // DER encoded CRL
|
||||||
|
Number *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *X509Revoking) Revoke(revokeCertificate *RevokeCertificate) (*pkix.RevokedCertificate, error) {
|
func (r *X509Revoking) Revoke(revokeCertificate *RevokeCertificate) (*pkix.RevokedCertificate, error) {
|
||||||
|
@ -146,7 +147,7 @@ func (r *X509Revoking) CreateCRL() (*CRLInformation, error) {
|
||||||
return nil, fmt.Errorf("could not sign revocation list: %w", err)
|
return nil, fmt.Errorf("could not sign revocation list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &CRLInformation{CRL: list}, nil
|
return &CRLInformation{CRL: list, Number: nextNumber}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewX509Revoking(
|
func NewX509Revoking(
|
||||||
|
@ -159,7 +160,8 @@ func NewX509Revoking(
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
Data []byte
|
CRLData []byte
|
||||||
|
Number *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type FetchCRLHandler struct {
|
type FetchCRLHandler struct {
|
||||||
|
@ -181,5 +183,5 @@ func (h *FetchCRLHandler) FetchCRL(issuerID string) (*Result, error) {
|
||||||
return nil, fmt.Errorf("could not create CRL for issuer ID %s: %w", issuerID, err)
|
return nil, fmt.Errorf("could not create CRL for issuer ID %s: %w", issuerID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Result{Data: currentCRL.CRL}, nil
|
return &Result{CRLData: currentCRL.CRL, Number: currentCRL.Number}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue