Implement configuration support for CA profiles
This commit is contained in:
parent
f98840bf9e
commit
1031ee3118
3 changed files with 99 additions and 3 deletions
|
@ -31,6 +31,8 @@ import (
|
|||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"git.cacert.org/cacert-gosigner/pkg/messages"
|
||||
|
||||
"git.cacert.org/cacert-gosigner/internal/x509/openssl"
|
||||
"git.cacert.org/cacert-gosigner/internal/x509/revoking"
|
||||
"git.cacert.org/cacert-gosigner/internal/x509/signing"
|
||||
|
@ -540,6 +542,7 @@ type CaCertificateEntry struct {
|
|||
KeyPair crypto.Signer
|
||||
Parent string
|
||||
Storage string
|
||||
Profiles []messages.CAProfile
|
||||
}
|
||||
|
||||
func (c *CaCertificateEntry) UnmarshalYAML(value *yaml.Node) error {
|
||||
|
@ -551,6 +554,10 @@ func (c *CaCertificateEntry) UnmarshalYAML(value *yaml.Node) error {
|
|||
ExtKeyUsage []string `yaml:"ext-key-usages,omitempty"`
|
||||
Parent string `yaml:"parent"`
|
||||
Storage string `yaml:"storage"`
|
||||
Profiles []struct {
|
||||
Name string `yaml:"name"`
|
||||
UseFor string `yaml:"use-for"`
|
||||
} `yaml:"profiles"`
|
||||
}
|
||||
|
||||
err := value.Decode(&m)
|
||||
|
@ -590,6 +597,22 @@ func (c *CaCertificateEntry) UnmarshalYAML(value *yaml.Node) error {
|
|||
c.Storage = "default"
|
||||
}
|
||||
|
||||
if m.Profiles != nil {
|
||||
c.Profiles = make([]messages.CAProfile, len(m.Profiles))
|
||||
|
||||
for i, prof := range m.Profiles {
|
||||
usage, err := messages.ParseUsage(prof.UseFor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("config error: %w", err)
|
||||
}
|
||||
|
||||
c.Profiles[i] = messages.CAProfile{
|
||||
Name: prof.Name,
|
||||
UseFor: usage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ import (
|
|||
"github.com/ThalesIgnite/crypto11"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"git.cacert.org/cacert-gosigner/pkg/messages"
|
||||
|
||||
"git.cacert.org/cacert-gosigner/internal/config"
|
||||
"git.cacert.org/cacert-gosigner/internal/health"
|
||||
)
|
||||
|
@ -68,7 +70,7 @@ func (a *Access) Healthy() (*health.Info, error) {
|
|||
|
||||
moreInfo := make(map[string]string)
|
||||
|
||||
const checkFailed = "failed"
|
||||
var checkFailed = messages.CertificateInfo{Status: "failed", Signing: false}.String()
|
||||
|
||||
for _, ca := range a.signerConfig.RootCAs() {
|
||||
infoKey := fmt.Sprintf("root-%s", ca)
|
||||
|
@ -82,7 +84,12 @@ func (a *Access) Healthy() (*health.Info, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
moreInfo[infoKey] = fmt.Sprintf("ok, valid until %s", cert.NotAfter.UTC().Format(time.RFC3339))
|
||||
moreInfo[infoKey] = messages.CertificateInfo{
|
||||
Status: "ok",
|
||||
Signing: false,
|
||||
Profiles: []messages.CAProfile{},
|
||||
ValidUntil: cert.NotAfter.UTC(),
|
||||
}.String()
|
||||
}
|
||||
|
||||
for _, ca := range a.signerConfig.SubordinateCAs() {
|
||||
|
@ -115,7 +122,12 @@ func (a *Access) Healthy() (*health.Info, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
moreInfo[infoKey] = fmt.Sprintf("ok, valid until %s", cert.NotAfter.UTC().Format(time.RFC3339))
|
||||
moreInfo[infoKey] = messages.CertificateInfo{
|
||||
Status: "ok",
|
||||
Signing: true,
|
||||
Profiles: def.Profiles,
|
||||
ValidUntil: cert.NotAfter.UTC(),
|
||||
}.String()
|
||||
}
|
||||
|
||||
return &health.Info{
|
||||
|
|
|
@ -22,6 +22,7 @@ package messages
|
|||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
@ -144,6 +145,66 @@ func (i *HealthInfo) String() string {
|
|||
return builder.String()
|
||||
}
|
||||
|
||||
type ProfileUsage string
|
||||
|
||||
const (
|
||||
UsageOcsp ProfileUsage = "ocsp"
|
||||
UsagePerson ProfileUsage = "person"
|
||||
UsageClient ProfileUsage = "client"
|
||||
UsageCode ProfileUsage = "code"
|
||||
UsageServer ProfileUsage = "server"
|
||||
)
|
||||
|
||||
var validProfileUsages = map[string]ProfileUsage{
|
||||
"ocsp": UsageOcsp,
|
||||
"person": UsagePerson,
|
||||
"client": UsageClient,
|
||||
"code": UsageCode,
|
||||
"server": UsageServer,
|
||||
}
|
||||
|
||||
func ParseUsage(u string) (ProfileUsage, error) {
|
||||
usage, ok := validProfileUsages[u]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("unsupported profile usage: %s", u)
|
||||
}
|
||||
|
||||
return usage, nil
|
||||
}
|
||||
|
||||
type CAProfile struct {
|
||||
Name string `json:"name"`
|
||||
UseFor ProfileUsage `json:"use-for"`
|
||||
}
|
||||
|
||||
func (p CAProfile) String() string {
|
||||
return fmt.Sprintf("profile['%s': '%s']", p.Name, p.UseFor)
|
||||
}
|
||||
|
||||
type CertificateInfo struct {
|
||||
Status string `json:"status"`
|
||||
Signing bool `json:"signing"`
|
||||
Profiles []CAProfile `json:"profiles"`
|
||||
ValidUntil time.Time `json:"valid-until"`
|
||||
}
|
||||
|
||||
func (i CertificateInfo) String() string {
|
||||
marshal, _ := json.Marshal(i)
|
||||
|
||||
return string(marshal)
|
||||
}
|
||||
|
||||
func (i *HealthInfo) ParseCertificateInfo(info string) (*CertificateInfo, error) {
|
||||
certInfo := CertificateInfo{}
|
||||
|
||||
err := json.Unmarshal([]byte(info), &certInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse certificate information: %w", err)
|
||||
}
|
||||
|
||||
return &certInfo, nil
|
||||
}
|
||||
|
||||
type HealthResponse struct {
|
||||
Version string `msgpack:"version"`
|
||||
Healthy bool `msgpack:"healthy"`
|
||||
|
|
Loading…
Reference in a new issue