forked from TrueCloudLab/certificates
Add JWK provisioner to generic config.
Fix linter errors.
This commit is contained in:
parent
536536c92d
commit
47a30f1524
3 changed files with 64 additions and 37 deletions
|
@ -163,7 +163,7 @@ func onboardAction(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func onboardPKI(config onboardingConfiguration) (*config.Config, string, error) {
|
func onboardPKI(config onboardingConfiguration) (*config.Config, string, error) {
|
||||||
var opts = []pki.PKIOption{
|
var opts = []pki.Option{
|
||||||
pki.WithAddress(config.Address),
|
pki.WithAddress(config.Address),
|
||||||
pki.WithDNSNames([]string{config.DNS}),
|
pki.WithDNSNames([]string{config.DNS}),
|
||||||
pki.WithProvisioner("admin"),
|
pki.WithProvisioner("admin"),
|
||||||
|
|
30
pki/helm.go
30
pki/helm.go
|
@ -6,14 +6,15 @@ import (
|
||||||
|
|
||||||
"github.com/Masterminds/sprig/v3"
|
"github.com/Masterminds/sprig/v3"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/certificates/authority"
|
||||||
authconfig "github.com/smallstep/certificates/authority/config"
|
authconfig "github.com/smallstep/certificates/authority/config"
|
||||||
"github.com/smallstep/certificates/authority/provisioner"
|
"github.com/smallstep/certificates/authority/provisioner"
|
||||||
"go.step.sm/linkedca"
|
"go.step.sm/linkedca"
|
||||||
)
|
)
|
||||||
|
|
||||||
type helmVariables struct {
|
type helmVariables struct {
|
||||||
linkedca.Configuration
|
*linkedca.Configuration
|
||||||
Defaults linkedca.Defaults
|
Defaults *linkedca.Defaults
|
||||||
Password string
|
Password string
|
||||||
SSH struct {
|
SSH struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
|
@ -33,19 +34,22 @@ func (p *PKI) WriteHelmTemplate(w io.Writer) error {
|
||||||
p.Ssh = nil
|
p.Ssh = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert provisioner to ca.json
|
||||||
|
provisioners := make([]provisioner.Interface, len(p.Authority.Provisioners))
|
||||||
|
for i, p := range p.Authority.Provisioners {
|
||||||
|
pp, err := authority.ProvisionerToCertificates(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
provisioners[i] = pp
|
||||||
|
}
|
||||||
|
|
||||||
if err := tmpl.Execute(w, helmVariables{
|
if err := tmpl.Execute(w, helmVariables{
|
||||||
Configuration: p.Configuration,
|
Configuration: &p.Configuration,
|
||||||
Defaults: p.Defaults,
|
Defaults: &p.Defaults,
|
||||||
Password: "asdf",
|
Password: "",
|
||||||
TLS: authconfig.DefaultTLSOptions,
|
TLS: authconfig.DefaultTLSOptions,
|
||||||
Provisioners: []provisioner.Interface{
|
Provisioners: provisioners,
|
||||||
&provisioner.JWK{
|
|
||||||
Name: p.options.provisioner,
|
|
||||||
Type: "JWK",
|
|
||||||
Key: p.ottPublicKey,
|
|
||||||
EncryptedKey: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrap(err, "error executing helm template")
|
return errors.Wrap(err, "error executing helm template")
|
||||||
}
|
}
|
||||||
|
|
69
pki/pki.go
69
pki/pki.go
|
@ -166,81 +166,81 @@ type options struct {
|
||||||
deploymentType DeploymentType
|
deploymentType DeploymentType
|
||||||
}
|
}
|
||||||
|
|
||||||
// PKIOption is the type of a configuration option on the pki constructor.
|
// Option is the type of a configuration option on the pki constructor.
|
||||||
type PKIOption func(p *PKI)
|
type Option func(p *PKI)
|
||||||
|
|
||||||
// WithAddress sets the listen address of step-ca.
|
// WithAddress sets the listen address of step-ca.
|
||||||
func WithAddress(s string) PKIOption {
|
func WithAddress(s string) Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.Address = s
|
p.Address = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCaUrl sets the default ca-url of step-ca.
|
// WithCaURL sets the default ca-url of step-ca.
|
||||||
func WithCaUrl(s string) PKIOption {
|
func WithCaURL(s string) Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.Defaults.CaUrl = s
|
p.Defaults.CaUrl = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithDNSNames sets the SANs of step-ca.
|
// WithDNSNames sets the SANs of step-ca.
|
||||||
func WithDNSNames(s []string) PKIOption {
|
func WithDNSNames(s []string) Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.DnsNames = s
|
p.DnsNames = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithProvisioner defines the name of the default provisioner.
|
// WithProvisioner defines the name of the default provisioner.
|
||||||
func WithProvisioner(s string) PKIOption {
|
func WithProvisioner(s string) Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.provisioner = s
|
p.options.provisioner = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithPKIOnly will only generate the PKI without the step-ca config files.
|
// WithPKIOnly will only generate the PKI without the step-ca config files.
|
||||||
func WithPKIOnly() PKIOption {
|
func WithPKIOnly() Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.pkiOnly = true
|
p.options.pkiOnly = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithACME enables acme provisioner in step-ca.
|
// WithACME enables acme provisioner in step-ca.
|
||||||
func WithACME() PKIOption {
|
func WithACME() Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.enableACME = true
|
p.options.enableACME = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSSH enables ssh in step-ca.
|
// WithSSH enables ssh in step-ca.
|
||||||
func WithSSH() PKIOption {
|
func WithSSH() Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.enableSSH = true
|
p.options.enableSSH = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithAdmin enables the admin api in step-ca.
|
// WithAdmin enables the admin api in step-ca.
|
||||||
func WithAdmin() PKIOption {
|
func WithAdmin() Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.enableAdmin = true
|
p.options.enableAdmin = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithNoDB disables the db in step-ca.
|
// WithNoDB disables the db in step-ca.
|
||||||
func WithNoDB() PKIOption {
|
func WithNoDB() Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.noDB = true
|
p.options.noDB = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithHelm configures the pki to create a helm values.yaml.
|
// WithHelm configures the pki to create a helm values.yaml.
|
||||||
func WithHelm() PKIOption {
|
func WithHelm() Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.isHelm = true
|
p.options.isHelm = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithDeploymentType defines the deployment type of step-ca.
|
// WithDeploymentType defines the deployment type of step-ca.
|
||||||
func WithDeploymentType(dt DeploymentType) PKIOption {
|
func WithDeploymentType(dt DeploymentType) Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
p.options.deploymentType = dt
|
p.options.deploymentType = dt
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ type PKI struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new PKI configuration.
|
// New creates a new PKI configuration.
|
||||||
func New(o apiv1.Options, opts ...PKIOption) (*PKI, error) {
|
func New(o apiv1.Options, opts ...Option) (*PKI, error) {
|
||||||
caService, err := cas.New(context.Background(), o)
|
caService, err := cas.New(context.Background(), o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -284,10 +284,11 @@ func New(o apiv1.Options, opts ...PKIOption) (*PKI, error) {
|
||||||
|
|
||||||
p := &PKI{
|
p := &PKI{
|
||||||
Configuration: linkedca.Configuration{
|
Configuration: linkedca.Configuration{
|
||||||
Address: "127.0.0.1:9000",
|
Address: "127.0.0.1:9000",
|
||||||
DnsNames: []string{"127.0.0.1"},
|
DnsNames: []string{"127.0.0.1"},
|
||||||
Ssh: &linkedca.SSH{},
|
Ssh: &linkedca.SSH{},
|
||||||
Files: make(map[string][]byte),
|
Authority: &linkedca.Authority{},
|
||||||
|
Files: make(map[string][]byte),
|
||||||
},
|
},
|
||||||
casOptions: o,
|
casOptions: o,
|
||||||
caCreator: caCreator,
|
caCreator: caCreator,
|
||||||
|
@ -395,6 +396,28 @@ func (p *PKI) GenerateKeyPairs(pass []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add JWK provisioner to the configuration.
|
||||||
|
publicKey, err := json.Marshal(p.ottPublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error marshaling public key")
|
||||||
|
}
|
||||||
|
encryptedKey, err := p.ottPrivateKey.CompactSerialize()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error serializing private key")
|
||||||
|
}
|
||||||
|
p.Authority.Provisioners = append(p.Authority.Provisioners, &linkedca.Provisioner{
|
||||||
|
Type: linkedca.Provisioner_JWK,
|
||||||
|
Name: p.options.provisioner,
|
||||||
|
Details: &linkedca.ProvisionerDetails{
|
||||||
|
Data: &linkedca.ProvisionerDetails_JWK{
|
||||||
|
JWK: &linkedca.JWKProvisioner{
|
||||||
|
PublicKey: publicKey,
|
||||||
|
EncryptedPrivateKey: []byte(encryptedKey),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,11 +616,11 @@ type caDefaults struct {
|
||||||
Root string `json:"root"`
|
Root string `json:"root"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option is the type for modifiers over the auth config object.
|
// ConfigOption is the type for modifiers over the auth config object.
|
||||||
type Option func(c *authconfig.Config) error
|
type ConfigOption func(c *authconfig.Config) error
|
||||||
|
|
||||||
// GenerateConfig returns the step certificates configuration.
|
// GenerateConfig returns the step certificates configuration.
|
||||||
func (p *PKI) GenerateConfig(opt ...Option) (*authconfig.Config, error) {
|
func (p *PKI) GenerateConfig(opt ...ConfigOption) (*authconfig.Config, error) {
|
||||||
var authorityOptions *apiv1.Options
|
var authorityOptions *apiv1.Options
|
||||||
if !p.casOptions.Is(apiv1.SoftCAS) {
|
if !p.casOptions.Is(apiv1.SoftCAS) {
|
||||||
authorityOptions = &p.casOptions
|
authorityOptions = &p.casOptions
|
||||||
|
@ -726,7 +749,7 @@ func (p *PKI) GenerateConfig(opt ...Option) (*authconfig.Config, error) {
|
||||||
|
|
||||||
// Save stores the pki on a json file that will be used as the certificate
|
// Save stores the pki on a json file that will be used as the certificate
|
||||||
// authority configuration.
|
// authority configuration.
|
||||||
func (p *PKI) Save(opt ...Option) error {
|
func (p *PKI) Save(opt ...ConfigOption) error {
|
||||||
// Write generated files
|
// Write generated files
|
||||||
if err := p.WriteFiles(); err != nil {
|
if err := p.WriteFiles(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in a new issue