From 28ff122f832fceeee6c99b9abb48a9b8b99032de Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Thu, 9 Jul 2020 11:40:37 -0700 Subject: [PATCH] Add certificate requests in the templates. --- x509util/certificate.go | 2 +- x509util/options.go | 17 ++++++++++------- x509util/templates.go | 15 +++++++++++---- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/x509util/certificate.go b/x509util/certificate.go index a01022d4..c5569ddd 100644 --- a/x509util/certificate.go +++ b/x509util/certificate.go @@ -43,7 +43,7 @@ func NewCertificate(cr *x509.CertificateRequest, opts ...Option) (*Certificate, return nil, errors.Wrap(err, "error validating certificate request") } - o, err := new(Options).apply(opts) + o, err := new(Options).apply(cr, opts) if err != nil { return nil, err } diff --git a/x509util/options.go b/x509util/options.go index 2915110e..9a061bed 100644 --- a/x509util/options.go +++ b/x509util/options.go @@ -2,6 +2,7 @@ package x509util import ( "bytes" + "crypto/x509" "io/ioutil" "text/template" @@ -15,9 +16,9 @@ type Options struct { CertBuffer *bytes.Buffer } -func (o *Options) apply(opts []Option) (*Options, error) { +func (o *Options) apply(cr *x509.CertificateRequest, opts []Option) (*Options, error) { for _, fn := range opts { - if err := fn(o); err != nil { + if err := fn(cr, o); err != nil { return o, err } } @@ -25,18 +26,19 @@ func (o *Options) apply(opts []Option) (*Options, error) { } // Option is the type used as a variadic argument in NewCertificate. -type Option func(o *Options) error +type Option func(cr *x509.CertificateRequest, o *Options) error // WithTemplate is an options that executes the given template text with the // given data. -func WithTemplate(text string, data map[string]interface{}) Option { - return func(o *Options) error { +func WithTemplate(text string, data TemplateData) Option { + return func(cr *x509.CertificateRequest, o *Options) error { tmpl, err := template.New("template").Funcs(sprig.TxtFuncMap()).Parse(text) if err != nil { return errors.Wrapf(err, "error parsing template") } buf := new(bytes.Buffer) + data.SetCertificateRequest(cr) if err := tmpl.Execute(buf, data); err != nil { return errors.Wrapf(err, "error executing template") } @@ -47,8 +49,8 @@ func WithTemplate(text string, data map[string]interface{}) Option { // WithTemplateFile is an options that reads the template file and executes it // with the given data. -func WithTemplateFile(path string, data map[string]interface{}) Option { - return func(o *Options) error { +func WithTemplateFile(path string, data TemplateData) Option { + return func(cr *x509.CertificateRequest, o *Options) error { filename := config.StepAbs(path) b, err := ioutil.ReadFile(filename) if err != nil { @@ -61,6 +63,7 @@ func WithTemplateFile(path string, data map[string]interface{}) Option { } buf := new(bytes.Buffer) + data.SetCertificateRequest(cr) if err := tmpl.Execute(buf, data); err != nil { return errors.Wrapf(err, "error executing %s", path) } diff --git a/x509util/templates.go b/x509util/templates.go index 44c8138f..0467229e 100644 --- a/x509util/templates.go +++ b/x509util/templates.go @@ -1,10 +1,13 @@ package x509util +import "crypto/x509" + const ( - UserKey = "User" - SubjectKey = "Subject" - SANsKey = "SANs" - TokenKey = "Token" + UserKey = "User" + SubjectKey = "Subject" + SANsKey = "SANs" + TokenKey = "Token" + CertificateRequestKey = "CR" ) // TemplateData is an alias for map[string]interface{}. It represents the data @@ -31,6 +34,10 @@ func (t TemplateData) SetToken(v interface{}) { t[TokenKey] = v } +func (t TemplateData) SetCertificateRequest(cr *x509.CertificateRequest) { + t[CertificateRequestKey] = newCertificateRequest(cr) +} + const DefaultLeafTemplate = `{ "subject": {{ toJson .Subject }}, "sans": {{ toJson .SANs }},