From 51afebf2c12f4e1a0b95406688da607ddbf3a760 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 1 Dec 2022 11:34:07 +0100 Subject: [PATCH] Test and refactor messages - add unit tests for all handwritten code in messages package - use uuid.NewString() instead of uuid.NewUUID() to avoid unnecessary error handling - sort code in messages.go to put type related code close to each other - move checkFailed from hsm.Access.Healthy method to messages.CertificateInfoFailed - add typing for Status field of messages.CertificateInfo --- cmd/clientsim/main.go | 29 +- internal/hsm/hsm.go | 14 +- pkg/messages/messages.go | 215 +++++++--- pkg/messages/messages_test.go | 608 ++++++++++++++++++++++++++++ pkg/messages/resolver.msgpackgen.go | 246 +++++------ 5 files changed, 896 insertions(+), 216 deletions(-) create mode 100644 pkg/messages/messages_test.go diff --git a/cmd/clientsim/main.go b/cmd/clientsim/main.go index 5249405..19b3913 100644 --- a/cmd/clientsim/main.go +++ b/cmd/clientsim/main.go @@ -41,21 +41,14 @@ type TestCommandGenerator struct { } func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error { - var ( - announce *messages.CommandAnnounce - err error - ) - // write some leading garbage to test signer robustness _, _ = io.CopyN(os.Stdout, rand.Reader, 50) //nolint:gomnd - announce, err = messages.BuildCommandAnnounce(messages.CmdHealth) - if err != nil { - return fmt.Errorf("build command announce failed: %w", err) + g.commands <- &protocol.Command{ + Announce: messages.BuildCommandAnnounce(messages.CmdHealth), + Command: &messages.HealthCommand{}, } - g.commands <- &protocol.Command{Announce: announce, Command: &messages.HealthCommand{}} - const ( healthInterval = 5 * time.Second crlInterval = 15 * time.Minute @@ -66,13 +59,8 @@ func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error { 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{ - Announce: announce, + Announce: messages.BuildCommandAnnounce(messages.CmdFetchCRL), Command: &messages.FetchCRLCommand{IssuerID: "sub-ecc_person_2022"}, } @@ -92,20 +80,15 @@ func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error { return nil case <-healthTimer.C: - announce, err = messages.BuildCommandAnnounce(messages.CmdHealth) - if err != nil { - return fmt.Errorf("build command announce failed: %w", err) - } - g.commands <- &protocol.Command{ - Announce: announce, + Announce: messages.BuildCommandAnnounce(messages.CmdHealth), Command: &messages.HealthCommand{}, } healthTimer.Reset(healthInterval) case <-crlTimer.C: g.commands <- &protocol.Command{ - Announce: announce, + Announce: messages.BuildCommandAnnounce(messages.CmdFetchCRL), Command: &messages.FetchCRLCommand{IssuerID: "sub-ecc_person_2022"}, } } diff --git a/internal/hsm/hsm.go b/internal/hsm/hsm.go index f3bc308..b8fafa3 100644 --- a/internal/hsm/hsm.go +++ b/internal/hsm/hsm.go @@ -69,8 +69,6 @@ func (a *Access) Healthy() (*health.Info, error) { moreInfo := make(map[string]string) - var checkFailed = messages.CertificateInfo{Status: "failed", Signing: false}.String() - for _, ca := range a.signerConfig.RootCAs() { infoKey := fmt.Sprintf("root-%s", ca) @@ -78,13 +76,13 @@ func (a *Access) Healthy() (*health.Info, error) { if err != nil { healthy = false - moreInfo[infoKey] = checkFailed + moreInfo[infoKey] = messages.CertificateInfoFailed.String() continue } moreInfo[infoKey] = messages.CertificateInfo{ - Status: "ok", + Status: messages.CertStatusOk, Signing: false, Profiles: []messages.CAProfile{}, ValidUntil: cert.NotAfter.UTC(), @@ -98,7 +96,7 @@ func (a *Access) Healthy() (*health.Info, error) { if err != nil { healthy = false - moreInfo[infoKey] = checkFailed + moreInfo[infoKey] = messages.CertificateInfoFailed.String() continue } @@ -107,7 +105,7 @@ func (a *Access) Healthy() (*health.Info, error) { if err != nil { healthy = false - moreInfo[infoKey] = checkFailed + moreInfo[infoKey] = messages.CertificateInfoFailed.String() continue } @@ -116,13 +114,13 @@ func (a *Access) Healthy() (*health.Info, error) { if err != nil { healthy = false - moreInfo[infoKey] = checkFailed + moreInfo[infoKey] = messages.CertificateInfoFailed.String() continue } moreInfo[infoKey] = messages.CertificateInfo{ - Status: "ok", + Status: messages.CertStatusOk, Signing: true, Profiles: def.Profiles, ValidUntil: cert.NotAfter.UTC(), diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go index e45f7c1..3257367 100644 --- a/pkg/messages/messages.go +++ b/pkg/messages/messages.go @@ -26,12 +26,12 @@ import ( "encoding/pem" "fmt" "math/big" + "sort" "strings" "time" // required for msgpackgen _ "github.com/dave/jennifer" - "github.com/google/uuid" ) @@ -91,6 +91,12 @@ func (r *CommandAnnounce) String() string { return fmt.Sprintf("code=%s, id=%s, created=%s", r.Code, r.ID, r.Created.Format(time.RFC3339)) } +func BuildCommandAnnounce(code CommandCode) *CommandAnnounce { + commandID := uuid.NewString() + + return &CommandAnnounce{Code: code, ID: commandID, Created: time.Now().UTC()} +} + type ResponseAnnounce struct { Code ResponseCode `msgpack:"code"` Created time.Time `msgpack:"created"` @@ -101,6 +107,17 @@ func (r *ResponseAnnounce) String() string { return fmt.Sprintf("code=%s, id=%s, created=%s", r.Code, r.ID, r.Created.Format(time.RFC3339)) } +func BuildResponseAnnounce(code ResponseCode, commandID string) *ResponseAnnounce { + return &ResponseAnnounce{Code: code, ID: commandID, Created: time.Now().UTC()} +} + +type HealthCommand struct { +} + +func (h *HealthCommand) String() string { + return "" +} + type FetchCRLCommand struct { IssuerID string `msgpack:"issuer_id"` LastKnownID []byte `msgpack:"last_known_id"` @@ -112,61 +129,97 @@ func (f *FetchCRLCommand) String() string { _, _ = fmt.Fprintf(builder, "issuerId='%s'", f.IssuerID) if f.LastKnownID != nil { - _, _ = fmt.Fprintf(builder, ", lastKnownId=0x%s", new(big.Int).SetBytes(f.LastKnownID).Text(16)) + _, _ = fmt.Fprintf(builder, ", lastKnownId=0x%x", new(big.Int).SetBytes(f.LastKnownID)) } return builder.String() } -type HealthCommand struct { -} +type ProfileUsage uint8 -func (h *HealthCommand) String() string { - return "" -} +const ( + UsageInvalid ProfileUsage = iota + + UsageOCSP + + UsageClient + UsageCode + UsagePerson + UsageServer + UsageServerClient + + UsageOrgClient + UsageOrgCode + UsageOrgEmail + UsageOrgPerson + UsageOrgServer + UsageOrgServerClient +) -type HealthInfo struct { - Source string - Healthy bool - MoreInfo map[string]string +var validProfileUsages = map[string]ProfileUsage{ + "ocsp": UsageOCSP, + + "client": UsageClient, + "code": UsageCode, + "person": UsagePerson, + "server": UsageServer, + "server_client": UsageServerClient, + + "org_client": UsageOrgClient, + "org_code": UsageOrgCode, + "org_email": UsageOrgEmail, + "org_person": UsageOrgPerson, + "org_server": UsageOrgServer, + "org_server_client": UsageOrgServerClient, } -func (i *HealthInfo) String() string { - builder := &strings.Builder{} - - _, _ = fmt.Fprintf(builder, "source: %s, healthy: %v, [\n", i.Source, i.Healthy) +var profileUsageDetails = map[ProfileUsage]struct { + Name string + Description string +}{ + UsageInvalid: {"invalid", "Invalid certificate profile, not to be used"}, + + UsageOCSP: {"ocsp", "OCSP responder signing certificate"}, + + UsageClient: {"client", "machine TLS client certificate"}, + UsageCode: {"code", "individual code signing certificate"}, + UsagePerson: {"person", "person identity certificate"}, + UsageServer: {"server", "TLS server certificate"}, + UsageServerClient: {"server_client", "combined TLS server and client certificate"}, + + UsageOrgClient: {"org_client", "organization machine TLS client certificate"}, + UsageOrgCode: {"org_code", "organization code signing certificate"}, + UsageOrgEmail: {"org_email", "organization email certificate"}, + UsageOrgPerson: {"org_person", "organizational person identity certificate"}, + UsageOrgServer: {"org_server", "organization TLS server certificate"}, + UsageOrgServerClient: { + "org_server_client", + "combined organization TLS server and client certificate", + }, +} - for k, v := range i.MoreInfo { - _, _ = fmt.Fprintf(builder, " %s: '%s'\n", k, v) +func (p ProfileUsage) String() string { + name, ok := profileUsageDetails[p] + if !ok { + return fmt.Sprintf("unknown profile usage %d", p) } - _, _ = builder.WriteRune(']') - - return builder.String() + return name.Name } -type ProfileUsage string - -const ( - UsageOcsp ProfileUsage = "ocsp" - UsagePerson ProfileUsage = "person" - UsageClient ProfileUsage = "client" - UsageCode ProfileUsage = "code" - UsageServer ProfileUsage = "server" -) +func (p ProfileUsage) Description() string { + name, ok := profileUsageDetails[p] + if !ok { + return fmt.Sprintf("unknown profile usage %d", p) + } -var validProfileUsages = map[string]ProfileUsage{ - "ocsp": UsageOcsp, - "person": UsagePerson, - "client": UsageClient, - "code": UsageCode, - "server": UsageServer, + return name.Description } func ParseUsage(u string) (ProfileUsage, error) { usage, ok := validProfileUsages[u] if !ok { - return "", fmt.Errorf("unsupported profile usage: %s", u) + return UsageInvalid, fmt.Errorf("unsupported profile usage: %s", u) } return usage, nil @@ -181,11 +234,18 @@ func (p CAProfile) String() string { return fmt.Sprintf("profile['%s': '%s']", p.Name, p.UseFor) } +type CertificateStatus string + +const ( + CertStatusOk CertificateStatus = "ok" + CertStatusFailed CertificateStatus = "failed" +) + type CertificateInfo struct { - Status string `json:"status"` - Signing bool `json:"signing"` - Profiles []CAProfile `json:"profiles"` - ValidUntil time.Time `json:"valid-until"` + Status CertificateStatus `json:"status"` + Signing bool `json:"signing"` + Profiles []CAProfile `json:"profiles,omitempty"` + ValidUntil time.Time `json:"valid-until"` } func (i CertificateInfo) String() string { @@ -194,7 +254,12 @@ func (i CertificateInfo) String() string { return string(marshal) } -func (i *HealthInfo) ParseCertificateInfo(info string) (*CertificateInfo, error) { +var CertificateInfoFailed = CertificateInfo{ + Status: CertStatusFailed, + Signing: false, +} + +func ParseCertificateInfo(info string) (*CertificateInfo, error) { certInfo := CertificateInfo{} err := json.Unmarshal([]byte(info), &certInfo) @@ -205,6 +270,39 @@ func (i *HealthInfo) ParseCertificateInfo(info string) (*CertificateInfo, error) return &certInfo, nil } +type HealthInfo struct { + Source string + Healthy bool + MoreInfo map[string]string +} + +func (i *HealthInfo) String() string { + builder := &strings.Builder{} + + _, _ = fmt.Fprintf(builder, "source: %s, healthy: %v", i.Source, i.Healthy) + + if len(i.MoreInfo) > 0 { + keys := make([]string, 0, len(i.MoreInfo)) + parts := make([]string, len(i.MoreInfo)) + + for k := range i.MoreInfo { + keys = append(keys, k) + } + + sort.Strings(keys) + + for j, k := range keys { + parts[j] = fmt.Sprintf("'%s': '%s'", k, i.MoreInfo[k]) + } + + builder.WriteRune('[') + builder.WriteString(strings.Join(parts, ", ")) + builder.WriteRune(']') + } + + return builder.String() +} + type HealthResponse struct { Version string `msgpack:"version"` Healthy bool `msgpack:"healthy"` @@ -214,12 +312,18 @@ type HealthResponse struct { func (h *HealthResponse) String() string { builder := &strings.Builder{} - _, _ = fmt.Fprintf(builder, "signer version=%s, healthy=%v, health data:\n", h.Version, h.Healthy) + _, _ = fmt.Fprintf(builder, "signer version=%s, healthy=%v, health data=[", h.Version, h.Healthy) + + infos := make([]string, len(h.Info)) - for _, info := range h.Info { - _, _ = fmt.Fprintf(builder, " - %s", info) + for i, info := range h.Info { + infos[i] = fmt.Sprintf("{%s}", info) } + builder.WriteString(strings.Join(infos, ", ")) + + builder.WriteRune(']') + return builder.String() } @@ -236,11 +340,11 @@ func (r *FetchCRLResponse) String() string { _, _ = fmt.Fprintf( builder, - "issuer id=%s, delta CRL data=%t, unchanged=%t, CRL number=0x%s", + "issuer id=%s, delta=%t, unchanged=%t, CRL number=0x%x", r.IssuerID, r.IsDelta, r.UnChanged, - new(big.Int).SetBytes(r.CRLNumber).Text(16), + new(big.Int).SetBytes(r.CRLNumber), ) if r.UnChanged { @@ -248,7 +352,7 @@ func (r *FetchCRLResponse) String() string { } if r.IsDelta { - _, _ = fmt.Fprint(builder, ", delta CRL data not shown") + _, _ = fmt.Fprintf(builder, ", delta CRL data of %d bytes not shown", len(r.CRLData)) return builder.String() } @@ -262,9 +366,9 @@ func (r *FetchCRLResponse) String() string { _, _ = fmt.Fprintf( builder, - ", CRL info: issuer=%s, number=0x%s, next update=%s, revoked certificates=%d", + ", CRL info: issuer=%s, number=0x%x, next update=%s, revoked certificates=%d", revocationList.Issuer, - revocationList.Number.Text(16), + revocationList.Number, revocationList.NextUpdate, len(revocationList.RevokedCertificates), ) @@ -284,16 +388,3 @@ type ErrorResponse struct { func (e *ErrorResponse) String() string { return fmt.Sprintf("message=%s", e.Message) } - -func BuildCommandAnnounce(code CommandCode) (*CommandAnnounce, error) { - 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()} -} diff --git a/pkg/messages/messages_test.go b/pkg/messages/messages_test.go new file mode 100644 index 0000000..be5a195 --- /dev/null +++ b/pkg/messages/messages_test.go @@ -0,0 +1,608 @@ +/* +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 messages + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "fmt" + "math/big" + "strings" + "testing" + "time" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCommandCode_String(t *testing.T) { + goodVariants := []struct { + Name string + Value CommandCode + }{ + {"undefined", CmdUndef}, + {"health", CmdHealth}, + {"fetch-crl", CmdFetchCRL}, + } + + for _, v := range goodVariants { + t.Run(v.Name, func(t *testing.T) { + str := v.Value.String() + + assert.NotEmpty(t, str) + }) + } + + t.Run("unknown", func(t *testing.T) { + var unknown CommandCode = -1 + + str := unknown.String() + + assert.NotEmpty(t, str) + assert.Equal(t, "unknown -1", str) + }) +} + +func TestResponseCode_String(t *testing.T) { + goodVariants := []struct { + Name string + Value ResponseCode + }{ + {"undefined", RespUndef}, + {"error", RespError}, + {"health", RespHealth}, + {"fetch-crl", RespFetchCRL}, + } + + for _, v := range goodVariants { + t.Run(v.Name, func(t *testing.T) { + str := v.Value.String() + + assert.NotEmpty(t, str) + }) + } + + t.Run("unknown", func(t *testing.T) { + var unknown ResponseCode = -2 + + str := unknown.String() + + assert.NotEmpty(t, str) + assert.Equal(t, "unknown -2", str) + }) +} + +func TestBuildCommandAnnounce(t *testing.T) { + commands := []CommandCode{ + CmdUndef, + CmdHealth, + CmdFetchCRL, + } + + for _, c := range commands { + t.Run(c.String(), func(t *testing.T) { + announce := BuildCommandAnnounce(c) + + require.NotNil(t, announce) + + assert.Equal(t, c, announce.Code) + assert.NotEmpty(t, announce.ID) + assert.NotEmpty(t, announce.Created) + assert.True(t, announce.Created.Before(time.Now().UTC())) + }) + } +} + +func TestCommandAnnounce_String(t *testing.T) { + announce := BuildCommandAnnounce(CmdUndef) + + require.NotNil(t, announce) + + str := announce.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "code") + assert.Contains(t, str, "id") + assert.Contains(t, str, "created") +} + +func TestBuildResponseAnnounce(t *testing.T) { + responses := []ResponseCode{ + RespError, + RespUndef, + RespHealth, + RespFetchCRL, + } + + for _, r := range responses { + commandID := uuid.NewString() + + t.Run(r.String(), func(t *testing.T) { + announce := BuildResponseAnnounce(r, commandID) + + assert.NotNil(t, announce) + + assert.Equal(t, r, announce.Code) + assert.Equal(t, commandID, announce.ID) + assert.NotEmpty(t, announce.ID) + assert.NotEmpty(t, announce.Created) + assert.True(t, announce.Created.Before(time.Now().UTC())) + }) + } +} + +func TestResponseAnnounce_String(t *testing.T) { + announce := BuildResponseAnnounce(RespUndef, uuid.NewString()) + + require.NotNil(t, announce) + + str := announce.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "code") + assert.Contains(t, str, "id") + assert.Contains(t, str, "created") +} + +func TestHealthCommand_String(t *testing.T) { + command := &HealthCommand{} + + str := command.String() + + assert.Equal(t, "", str) +} + +func TestFetchCRLCommand_String(t *testing.T) { + t.Run("no-last-known", func(t *testing.T) { + cmd := &FetchCRLCommand{IssuerID: "issuer"} + + str := cmd.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "issuerId") + assert.NotContains(t, str, "lastKnownId") + assert.NotContains(t, str, "0x") + }) + + t.Run("with-last-known", func(t *testing.T) { + cmd := &FetchCRLCommand{ + IssuerID: "issuer", + LastKnownID: big.NewInt(255).Bytes(), + } + + str := cmd.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "issuerId") + assert.Contains(t, str, "lastKnownId") + assert.Contains(t, str, "0xff") + }) +} + +func TestProfileUsage_String(t *testing.T) { + okValues := []struct { + Name string + Usage ProfileUsage + }{ + {"invalid", UsageInvalid}, + {"ocsp", UsageOCSP}, + {"client", UsageClient}, + {"code", UsageCode}, + {"person", UsagePerson}, + {"server", UsageServer}, + {"server-client", UsageServerClient}, + {"org-client", UsageOrgClient}, + {"org-code", UsageOrgCode}, + {"org-email", UsageOrgEmail}, + {"org-person", UsageOrgPerson}, + {"org-server", UsageOrgServer}, + {"org-server-client", UsageOrgServerClient}, + } + + for _, v := range okValues { + t.Run(v.Name, func(t *testing.T) { + str := v.Usage.String() + + assert.NotEmpty(t, str) + assert.NotContains(t, str, "unknown profile usage") + }) + } + + t.Run("undefined", func(t *testing.T) { + str := ProfileUsage(255).String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "unknown profile usage") + assert.Contains(t, str, "255") + }) +} + +func TestProfileUsage_Description(t *testing.T) { + okValues := []struct { + Name string + Usage ProfileUsage + }{ + {"invalid", UsageInvalid}, + {"ocsp", UsageOCSP}, + {"client", UsageClient}, + {"code", UsageCode}, + {"person", UsagePerson}, + {"server", UsageServer}, + {"server-client", UsageServerClient}, + {"org-client", UsageOrgClient}, + {"org-code", UsageOrgCode}, + {"org-email", UsageOrgEmail}, + {"org-person", UsageOrgPerson}, + {"org-server", UsageOrgServer}, + {"org-server-client", UsageOrgServerClient}, + } + + for _, v := range okValues { + t.Run(v.Name, func(t *testing.T) { + str := v.Usage.Description() + + assert.NotEmpty(t, str) + assert.NotContains(t, str, "unknown profile usage") + assert.Greater(t, len(str), len(v.Name)) + }) + } + + t.Run("undefined", func(t *testing.T) { + str := ProfileUsage(255).Description() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "unknown profile usage") + assert.Contains(t, str, "255") + }) +} + +func TestParseUsage(t *testing.T) { + okValues := []string{ + "ocsp", "client", "code", "person", "server", "server_client", + "org_client", "org_code", "org_email", "org_person", "org_server", "org_server_client", + } + + for _, v := range okValues { + t.Run(v, func(t *testing.T) { + u, err := ParseUsage(v) + + assert.NoError(t, err) + assert.Greater(t, u, ProfileUsage(0)) + }) + } + + t.Run("invalid", func(t *testing.T) { + u, err := ParseUsage("foo") + + assert.Error(t, err) + assert.Equal(t, u, UsageInvalid) + }) +} + +func TestCAProfile_String(t *testing.T) { + profiles := []CAProfile{ + {Name: "test-client", UseFor: UsageClient}, + {Name: "test-code", UseFor: UsageCode}, + {Name: "test-ocsp", UseFor: UsageOCSP}, + {Name: "test-org-client", UseFor: UsageOrgClient}, + {Name: "test-org-code", UseFor: UsageOrgCode}, + {Name: "test-org-email", UseFor: UsageOrgEmail}, + {Name: "test-org-person", UseFor: UsageOrgPerson}, + {Name: "test-org-server", UseFor: UsageOrgServer}, + {Name: "test-org-server-client", UseFor: UsageOrgServerClient}, + {Name: "test-person", UseFor: UsagePerson}, + {Name: "test-server", UseFor: UsageServer}, + {Name: "test-server-client", UseFor: UsageServerClient}, + } + + for _, p := range profiles { + t.Run(p.Name, func(t *testing.T) { + str := p.String() + + assert.NotEmpty(t, str) + assert.True(t, strings.HasPrefix(str, "profile['")) + assert.True(t, strings.HasSuffix(str, "']")) + assert.Contains(t, str, "': '") + assert.Contains(t, str, p.Name) + assert.Contains(t, str, p.UseFor.String()) + }) + } +} + +func TestCertificateInfo_String(t *testing.T) { + infoInstances := []struct { + Name string + info CertificateInfo + }{ + {"failed", CertificateInfoFailed}, + {"ok", + CertificateInfo{ + Status: CertStatusOk, + Signing: true, + Profiles: []CAProfile{{ + Name: "test", + UseFor: UsageServer, + }}, + ValidUntil: time.Now().UTC(), + }, + }, + } + + for _, i := range infoInstances { + t.Run(i.Name, func(t *testing.T) { + str := i.info.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, fmt.Sprintf("%t", i.info.Signing)) + assert.True(t, strings.HasPrefix(str, "{")) + assert.True(t, strings.HasSuffix(str, "}")) + assert.Contains(t, str, "status") + assert.Contains(t, str, "signing") + + if len(i.info.Profiles) == 0 { + assert.NotContains(t, str, "profiles") + } else { + assert.Contains(t, str, "profiles") + } + + if i.info.ValidUntil.IsZero() { + assert.Contains(t, str, `"valid-until":"0001-01-01T00:00:00Z"`) + } else { + assert.Contains(t, str, "valid-until") + } + }) + } +} + +func TestParseCertificateInfo(t *testing.T) { + brokenVariants := []struct{ Name, Value string }{ + {"no json", "no json for you"}, + {"invalid-status", `{"status":"foo"`}, + {"invalid-date", `{"status":"failed","valid-until":"foo"`}, + } + + for _, v := range brokenVariants { + t.Run(v.Name, func(t *testing.T) { + i, err := ParseCertificateInfo(v.Value) + + assert.Error(t, err) + assert.Nil(t, i) + }) + } + + okVariants := []struct{ Name, Value string }{ + {"minimal", `{"status":"failed"}`}, + {"signing", `{"status":"ok","signing":true}`}, + {"with-date", `{"status":"ok","signing":false,"valid-until":"2022-12-31T23:59:59+01:00"}`}, + } + + for _, v := range okVariants { + t.Run(v.Name, func(t *testing.T) { + i, err := ParseCertificateInfo(v.Value) + + assert.NoError(t, err) + require.NotNil(t, i) + assert.NotEmpty(t, i.Status) + }) + } +} + +func TestHealthInfo_String(t *testing.T) { + t.Run("no-more-info", func(t *testing.T) { + i := &HealthInfo{Source: "test1", Healthy: true} + + str := i.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "source") + assert.Contains(t, str, "healthy") + assert.Contains(t, str, "true") + assert.NotContains(t, str, "[") + assert.NotContains(t, str, "]") + }) + + t.Run("with-more-info", func(t *testing.T) { + i := &HealthInfo{Source: "test2", Healthy: false, MoreInfo: map[string]string{"foo": "bar", "baz": "boo"}} + + str := i.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "source") + assert.Contains(t, str, "healthy") + assert.Contains(t, str, "false") + assert.Contains(t, str, "['baz': 'boo', 'foo': 'bar']") + }) +} + +func TestHealthResponse_String(t *testing.T) { + t.Run("no-data", func(t *testing.T) { + r := &HealthResponse{Version: "foo", Healthy: true} + + str := r.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "signer version") + assert.Contains(t, str, "foo") + assert.Contains(t, str, "healthy") + assert.Contains(t, str, "true") + assert.Contains(t, str, "[]") + }) + + t.Run("with-data", func(t *testing.T) { + r := &HealthResponse{ + Version: "foo", + Healthy: false, + Info: []*HealthInfo{ + {Source: "bar", Healthy: true}, + {Source: "baz", Healthy: false, MoreInfo: map[string]string{ + "alice": "good", + "malory": "bad", + }}, + }, + } + + str := r.String() + assert.NotEmpty(t, str) + assert.Contains(t, str, "signer version") + assert.Contains(t, str, "foo") + assert.Contains(t, str, "healthy") + assert.Contains(t, str, "false") + assert.NotContains(t, str, "[]") + assert.Contains(t, str, "bar") + assert.Contains(t, str, "baz") + assert.Contains(t, str, "alice") + assert.Contains(t, str, "good") + assert.Contains(t, str, "malory") + assert.Contains(t, str, "bad") + }) +} + +func TestFetchCRLResponse_String(t *testing.T) { + t.Run("unchanged", func(t *testing.T) { + r := &FetchCRLResponse{ + IssuerID: "deep-thought", + IsDelta: false, + UnChanged: true, + CRLNumber: big.NewInt(0x42).Bytes(), + } + + str := r.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "issuer id") + assert.Contains(t, str, "delta=false") + assert.Contains(t, str, "unchanged=true") + assert.Contains(t, str, "CRL number=0x42") + assert.NotContains(t, str, "delta CRL data") + assert.NotContains(t, str, "CERTIFICATE REVOCATION LIST") + }) + + t.Run("delta", func(t *testing.T) { + randomBytes := make([]byte, 100) + _, _ = rand.Read(randomBytes) + + r := &FetchCRLResponse{ + IssuerID: "deep-thought", + IsDelta: true, + UnChanged: false, + CRLData: randomBytes, + CRLNumber: big.NewInt(0x42).Bytes(), + } + + str := r.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "issuer id") + assert.Contains(t, str, "delta=true") + assert.Contains(t, str, "unchanged=false") + assert.Contains(t, str, "CRL number=0x42") + assert.Contains(t, str, "delta CRL data") + assert.Contains(t, str, "100 bytes") + assert.NotContains(t, str, "CERTIFICATE REVOCATION LIST") + }) + + t.Run("bad-crl", func(t *testing.T) { + randomBytes := make([]byte, 100) + _, _ = rand.Read(randomBytes) + + r := &FetchCRLResponse{ + IssuerID: "deep-thought", + IsDelta: false, + UnChanged: false, + CRLData: randomBytes, + CRLNumber: big.NewInt(0x42).Bytes(), + } + + str := r.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "issuer id") + assert.Contains(t, str, "delta=false") + assert.Contains(t, str, "unchanged=false") + assert.Contains(t, str, "CRL number=0x42") + assert.NotContains(t, str, "delta CRL data") + assert.NotContains(t, str, "CERTIFICATE REVOCATION LIST") + assert.Contains(t, str, "could not parse CRL") + }) + + t.Run("good-crl", func(t *testing.T) { + keyPair, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + + require.NoError(t, err) + + certTemplate := &x509.Certificate{ + BasicConstraintsValid: true, + IsCA: true, + Issuer: pkix.Name{Country: []string{"un"}, Organization: []string{"Acme Ltd."}, CommonName: "foo CA"}, + KeyUsage: x509.KeyUsageCRLSign | x509.KeyUsageCertSign, + MaxPathLen: 0, + MaxPathLenZero: false, + NotAfter: time.Now().AddDate(5, 0, 0), + NotBefore: time.Now(), + SerialNumber: big.NewInt(1), + SignatureAlgorithm: x509.ECDSAWithSHA256, + Subject: pkix.Name{Country: []string{"un"}, Organization: []string{"Acme Ltd."}, CommonName: "foo CA"}, + } + + certBytes, err := x509.CreateCertificate(rand.Reader, certTemplate, certTemplate, keyPair.Public(), keyPair) + + require.NoError(t, err) + + cert, _ := x509.ParseCertificate(certBytes) + + list, _ := x509.CreateRevocationList(rand.Reader, &x509.RevocationList{ + Number: big.NewInt(0x42), + Issuer: cert.Subject, + ThisUpdate: time.Now(), + NextUpdate: time.Now().Add(1 * time.Hour), + }, cert, keyPair) + + r := &FetchCRLResponse{ + IssuerID: "deep-thought", + IsDelta: false, + UnChanged: false, + CRLData: list, + CRLNumber: big.NewInt(0x42).Bytes(), + } + + str := r.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "issuer id") + assert.Contains(t, str, "delta=false") + assert.Contains(t, str, "unchanged=false") + assert.Contains(t, str, "CRL number=0x42") + assert.NotContains(t, str, "delta CRL data") + assert.Contains(t, str, "CERTIFICATE REVOCATION LIST") + assert.NotContains(t, str, "could not parse CRL") + }) +} + +func TestErrorResponse_String(t *testing.T) { + r := &ErrorResponse{Message: "kaput"} + + str := r.String() + + assert.NotEmpty(t, str) + assert.Contains(t, str, "message") + assert.Contains(t, str, "kaput") +} diff --git a/pkg/messages/resolver.msgpackgen.go b/pkg/messages/resolver.msgpackgen.go index 971ce01..1be380e 100644 --- a/pkg/messages/resolver.msgpackgen.go +++ b/pkg/messages/resolver.msgpackgen.go @@ -26,64 +26,64 @@ func ___encode(i interface{}) ([]byte, error) { // encodeAsArray func ___encodeAsArray(i interface{}) ([]byte, error) { switch v := i.(type) { - case FetchCRLCommand: + case HealthCommand: encoder := enc.NewEncoder() - size, err := ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) + size, err := ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) + b, offset, err := ___encodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) } return b, err - case *FetchCRLCommand: + case *HealthCommand: encoder := enc.NewEncoder() - size, err := ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) + size, err := ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) + b, offset, err := ___encodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) } return b, err - case HealthCommand: + case FetchCRLCommand: encoder := enc.NewEncoder() - size, err := ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) + size, err := ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) + b, offset, err := ___encodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) } return b, err - case *HealthCommand: + case *FetchCRLCommand: encoder := enc.NewEncoder() - size, err := ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) + size, err := ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) + b, offset, err := ___encodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) } return b, err case HealthInfo: @@ -213,64 +213,64 @@ func ___encodeAsArray(i interface{}) ([]byte, error) { // encodeAsMap func ___encodeAsMap(i interface{}) ([]byte, error) { switch v := i.(type) { - case FetchCRLCommand: + case HealthCommand: encoder := enc.NewEncoder() - size, err := ___calcMapSizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) + size, err := ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) + b, offset, err := ___encodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) } return b, err - case *FetchCRLCommand: + case *HealthCommand: encoder := enc.NewEncoder() - size, err := ___calcMapSizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) + size, err := ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) + b, offset, err := ___encodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) } return b, err - case HealthCommand: + case FetchCRLCommand: encoder := enc.NewEncoder() - size, err := ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) + size, err := ___calcMapSizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) + b, offset, err := ___encodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) } return b, err - case *HealthCommand: + case *FetchCRLCommand: encoder := enc.NewEncoder() - size, err := ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) + size, err := ___calcMapSizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder) if err != nil { return nil, err } encoder.MakeBytes(size) - b, offset, err := ___encodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) + b, offset, err := ___encodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0) if err != nil { return nil, err } if size != offset { - return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthCommand", size, offset) + return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset) } return b, err case HealthInfo: @@ -409,30 +409,30 @@ func ___decode(data []byte, i interface{}) (bool, error) { // decodeAsArray func ___decodeAsArray(data []byte, i interface{}) (bool, error) { switch v := i.(type) { - case *FetchCRLCommand: + case *HealthCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) + offset, err := ___decodeArrayHealthCommand_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 **FetchCRLCommand: + case **HealthCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0) + offset, err := ___decodeArrayHealthCommand_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 *HealthCommand: + case *FetchCRLCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) + offset, err := ___decodeArrayFetchCRLCommand_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 **HealthCommand: + case **FetchCRLCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0) + offset, err := ___decodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0) if err == nil && offset != decoder.Len() { return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) } @@ -500,30 +500,30 @@ func ___decodeAsArray(data []byte, i interface{}) (bool, error) { // decodeAsMap func ___decodeAsMap(data []byte, i interface{}) (bool, error) { switch v := i.(type) { - case *FetchCRLCommand: + case *HealthCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) + offset, err := ___decodeMapHealthCommand_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 **FetchCRLCommand: + case **HealthCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0) + offset, err := ___decodeMapHealthCommand_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 *HealthCommand: + case *FetchCRLCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) + offset, err := ___decodeMapFetchCRLCommand_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 **HealthCommand: + case **FetchCRLCommand: decoder := dec.NewDecoder(data) - offset, err := ___decodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0) + offset, err := ___decodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0) if err == nil && offset != decoder.Len() { return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) } @@ -588,6 +588,81 @@ func ___decodeAsMap(data []byte, i interface{}) (bool, error) { return false, nil } +// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand +func ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder) (int, error) { + size := 0 + size += encoder.CalcStructHeaderFix(0) + return size, nil +} + +// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand +func ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder) (int, error) { + size := 0 + size += encoder.CalcStructHeaderFix(0) + return size, nil +} + +// encode from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand +func ___encodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder, offset int) ([]byte, int, error) { + var err error + offset = encoder.WriteStructHeaderFixAsArray(0, offset) + return encoder.EncodedBytes(), offset, err +} + +// encode from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand +func ___encodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder, offset int) ([]byte, int, error) { + var err error + offset = encoder.WriteStructHeaderFixAsMap(0, offset) + return encoder.EncodedBytes(), offset, err +} + +// decode to git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand +func ___decodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *HealthCommand, decoder *dec.Decoder, offset int) (int, error) { + offset, err := decoder.CheckStructHeader(0, offset) + if err != nil { + return 0, err + } + return offset, err +} + +// decode to git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand +func ___decodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *HealthCommand, decoder *dec.Decoder, offset int) (int, error) { + keys := [][]byte{} + offset, err := decoder.CheckStructHeader(0, offset) + if err != nil { + return 0, err + } + count := 0 + for count < 0 { + 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 { + default: + return 0, fmt.Errorf("unknown key[%s] found", string(dataKey)) + } + } + return offset, err +} + // calculate size from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLCommand func ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLCommand, encoder *enc.Encoder) (int, error) { size := 0 @@ -774,81 +849,6 @@ func ___decodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377 return offset, err } -// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand -func ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder) (int, error) { - size := 0 - size += encoder.CalcStructHeaderFix(0) - return size, nil -} - -// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand -func ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder) (int, error) { - size := 0 - size += encoder.CalcStructHeaderFix(0) - return size, nil -} - -// encode from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand -func ___encodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder, offset int) ([]byte, int, error) { - var err error - offset = encoder.WriteStructHeaderFixAsArray(0, offset) - return encoder.EncodedBytes(), offset, err -} - -// encode from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand -func ___encodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder, offset int) ([]byte, int, error) { - var err error - offset = encoder.WriteStructHeaderFixAsMap(0, offset) - return encoder.EncodedBytes(), offset, err -} - -// decode to git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand -func ___decodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *HealthCommand, decoder *dec.Decoder, offset int) (int, error) { - offset, err := decoder.CheckStructHeader(0, offset) - if err != nil { - return 0, err - } - return offset, err -} - -// decode to git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand -func ___decodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *HealthCommand, decoder *dec.Decoder, offset int) (int, error) { - keys := [][]byte{} - offset, err := decoder.CheckStructHeader(0, offset) - if err != nil { - return 0, err - } - count := 0 - for count < 0 { - 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 { - default: - return 0, fmt.Errorf("unknown key[%s] found", string(dataKey)) - } - } - return offset, err -} - // calculate size from git.cacert.org/cacert-gosigner/pkg/messages.HealthInfo func ___calcArraySizeHealthInfo_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthInfo, encoder *enc.Encoder) (int, error) { size := 0