Prepend insecure to user and CR variables names.

This commit is contained in:
Mariano Cano 2020-07-14 17:12:07 -07:00
parent 69902b0153
commit b2ca3176f5
3 changed files with 54 additions and 31 deletions

View file

@ -19,9 +19,18 @@ func (fn certificateOptionsFunc) Options(so Options) []x509util.Option {
return fn(so)
}
// ProvisionerOptions are a collection of custom options that can be added to
// each provisioner.
type ProvisionerOptions struct {
// Template contains a X.509 certificate template. It can be a JSON template
// escaped in a string or it can be also encoded in base64.
Template string `json:"template"`
// TemplateFile points to a file containing a X.509 certificate template.
TemplateFile string `json:"templateFile"`
// TemplateData is a JSON object with variables that can be used in custom
// templates.
TemplateData json.RawMessage `json:"templateData"`
}
@ -63,11 +72,13 @@ func CustomTemplateOptions(o *ProvisionerOptions, data x509util.TemplateData, de
if len(so.TemplateData) > 0 {
userObject := make(map[string]interface{})
if err := json.Unmarshal(so.TemplateData, &userObject); err != nil {
data[x509util.UserKey] = map[string]interface{}{}
data.SetUserData(map[string]interface{}{})
} else {
data[x509util.UserKey] = userObject
data.SetUserData(userObject)
}
}
// Load a template from a file if Template is not defined.
if o.Template == "" && o.TemplateFile != "" {
return []x509util.Option{
x509util.WithTemplateFile(o.TemplateFile, data),

View file

@ -3,6 +3,7 @@ package x509util
import (
"bytes"
"crypto/x509"
"encoding/base64"
"io/ioutil"
"text/template"
@ -47,6 +48,19 @@ func WithTemplate(text string, data TemplateData) Option {
}
}
// WithTemplateBase64 is an options that executes the given template base64
// string with the given data.
func WithTemplateBase64(s string, data TemplateData) Option {
return func(cr *x509.CertificateRequest, o *Options) error {
b, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return errors.Wrap(err, "error decoding template")
}
fn := WithTemplate(string(b), data)
return fn(cr, o)
}
}
// WithTemplateFile is an options that reads the template file and executes it
// with the given data.
func WithTemplateFile(path string, data TemplateData) Option {
@ -56,18 +70,7 @@ func WithTemplateFile(path string, data TemplateData) Option {
if err != nil {
return errors.Wrapf(err, "error reading %s", path)
}
tmpl, err := template.New(path).Funcs(sprig.TxtFuncMap()).Parse(string(b))
if err != nil {
return errors.Wrapf(err, "error parsing %s", path)
}
buf := new(bytes.Buffer)
data.SetCertificateRequest(cr)
if err := tmpl.Execute(buf, data); err != nil {
return errors.Wrapf(err, "error executing %s", path)
}
o.CertBuffer = buf
return nil
fn := WithTemplate(string(b), data)
return fn(cr, o)
}
}

View file

@ -3,10 +3,11 @@ package x509util
import "crypto/x509"
const (
UserKey = "User"
SubjectKey = "Subject"
SANsKey = "SANs"
TokenKey = "Token"
InsecureKey = "Insecure"
UserKey = "User"
CertificateRequestKey = "CR"
)
@ -33,12 +34,16 @@ func (t TemplateData) Set(key string, v interface{}) {
t[key] = v
}
func (t TemplateData) SetUserData(v Subject) {
t[UserKey] = v
func (t TemplateData) SetInsecure(key string, v interface{}) {
if m, ok := t[InsecureKey].(TemplateData); ok {
m[key] = v
} else {
t[InsecureKey] = TemplateData{key: v}
}
}
func (t TemplateData) SetSubject(v Subject) {
t[SubjectKey] = v
t.Set(SubjectKey, v)
}
func (t TemplateData) SetCommonName(cn string) {
@ -48,15 +53,19 @@ func (t TemplateData) SetCommonName(cn string) {
}
func (t TemplateData) SetSANs(sans []string) {
t[SANsKey] = CreateSANs(sans)
t.Set(SANsKey, CreateSANs(sans))
}
func (t TemplateData) SetToken(v interface{}) {
t[TokenKey] = v
t.Set(TokenKey, v)
}
func (t TemplateData) SetUserData(v interface{}) {
t.SetInsecure(UserKey, v)
}
func (t TemplateData) SetCertificateRequest(cr *x509.CertificateRequest) {
t[CertificateRequestKey] = newCertificateRequest(cr)
t.SetInsecure(CertificateRequestKey, newCertificateRequest(cr))
}
// DefaultLeafTemplate is the default templated used to generate a leaf
@ -79,14 +88,14 @@ const DefaultLeafTemplate = `{
// keys.
const DefaultIIDLeafTemplate = `{
{{- if .SANs }}
"subject": {"commonName": "{{ .CR.Subject.CommonName }}"},
"subject": {"commonName": "{{ .Insecure.CR.Subject.CommonName }}"},
"sans": {{ toJson .SANs }},
{{- else }}
"subject": {{ toJson .CR.Subject }},
"dnsNames": {{ toJson .CR.DNSNames }},
"emailAddresses": {{ toJson .CR.EmailAddresses }},
"ipAddresses": {{ toJson .CR.IPAddresses }},
"uris": {{ toJson .CR.URIs }},
"subject": {{ toJson .Insecure.CR.Subject }},
"dnsNames": {{ toJson .Insecure.CR.DNSNames }},
"emailAddresses": {{ toJson .Insecure.CR.EmailAddresses }},
"ipAddresses": {{ toJson .Insecure.CR.IPAddresses }},
"uris": {{ toJson .Insecure.CR.URIs }},
{{- end }}
"keyUsage": ["keyEncipherment", "digitalSignature"],
"extKeyUsage": ["serverAuth", "clientAuth"]
@ -117,4 +126,4 @@ const DefaultRootTemplate = `{
// CertificateRequestTemplate is a template that will sign the given certificate
// request.
const CertificateRequestTemplate = `{{ toJson .CR }}`
const CertificateRequestTemplate = `{{ toJson .Insecure.CR }}`