diff --git a/authority/provisioner/k8sSA.go b/authority/provisioner/k8sSA.go index b63ce979..143e28f3 100644 --- a/authority/provisioner/k8sSA.go +++ b/authority/provisioner/k8sSA.go @@ -10,6 +10,7 @@ import ( "github.com/pkg/errors" "github.com/smallstep/certificates/errs" + "github.com/smallstep/certificates/x509util" "github.com/smallstep/cli/crypto/pemutil" "github.com/smallstep/cli/jose" "golang.org/x/crypto/ed25519" @@ -40,10 +41,11 @@ type k8sSAPayload struct { // entity trusted to make signature requests. type K8sSA struct { *base - Type string `json:"type"` - Name string `json:"name"` - Claims *Claims `json:"claims,omitempty"` - PubKeys []byte `json:"publicKeys,omitempty"` + Type string `json:"type"` + Name string `json:"name"` + PubKeys []byte `json:"publicKeys,omitempty"` + Claims *Claims `json:"claims,omitempty"` + Options *ProvisionerOptions `json:"options,omitempty"` claimer *Claimer audiences Audiences //kauthn kauthn.AuthenticationV1Interface @@ -208,7 +210,15 @@ func (p *K8sSA) AuthorizeSign(ctx context.Context, token string) ([]SignOption, return nil, errs.Wrap(http.StatusInternalServerError, err, "k8ssa.AuthorizeSign") } + // Certificate templates: on K8sSA the default template is the certificate + // request. + templateOptions, err := CustomTemplateOptions(p.Options, x509util.NewTemplateData(), x509util.CertificateRequestTemplate) + if err != nil { + return nil, errs.Wrap(http.StatusInternalServerError, err, "k8ssa.AuthorizeSign") + } + return []SignOption{ + templateOptions, // modifiers / withOptions newProvisionerExtensionOption(TypeK8sSA, p.Name, ""), profileDefaultDuration(p.claimer.DefaultTLSCertDuration()), diff --git a/x509util/extensions.go b/x509util/extensions.go index 8c7eecf4..ffecd2dd 100644 --- a/x509util/extensions.go +++ b/x509util/extensions.go @@ -4,6 +4,7 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/asn1" + "encoding/json" "fmt" "net" "net/url" @@ -76,6 +77,12 @@ func (e Extension) Set(c *x509.Certificate) { // object identifier or OID. type ObjectIdentifier asn1.ObjectIdentifier +// MarshalJSON implements the json.Marshaler interface and returns the string +// version of the asn1.ObjectIdentifier. +func (o ObjectIdentifier) MarshalJSON() ([]byte, error) { + return json.Marshal(asn1.ObjectIdentifier(o).String()) +} + // UnmarshalJSON implements the json.Unmarshaler interface and coverts a strings // like "2.5.29.17" into an ASN1 object identifier. func (o *ObjectIdentifier) UnmarshalJSON(data []byte) error { diff --git a/x509util/options.go b/x509util/options.go index cd261f2b..9a061bed 100644 --- a/x509util/options.go +++ b/x509util/options.go @@ -3,7 +3,6 @@ package x509util import ( "bytes" "crypto/x509" - "fmt" "io/ioutil" "text/template" @@ -43,7 +42,6 @@ func WithTemplate(text string, data TemplateData) Option { if err := tmpl.Execute(buf, data); err != nil { return errors.Wrapf(err, "error executing template") } - fmt.Println(buf.String()) o.CertBuffer = buf return nil } diff --git a/x509util/templates.go b/x509util/templates.go index bcbb7059..c7e8211e 100644 --- a/x509util/templates.go +++ b/x509util/templates.go @@ -113,3 +113,7 @@ const DefaultRootTemplate = `{ "maxPathLen": 1 } }` + +// CertificateRequestTemplate is a template that will sign the given certificate +// request. +const CertificateRequestTemplate = `{{ toJson .CR }}`