Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template funcs #302

Merged
merged 3 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions kms/capi/capi_no_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package capi

import (
"context"

"github.com/pkg/errors"
"go.step.sm/crypto/kms/apiv1"
)
Expand Down
5 changes: 3 additions & 2 deletions kms/capi/ncrypt_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import (
"encoding/binary"
"errors"
"fmt"
"golang.org/x/sys/windows"
"unsafe"

"golang.org/x/sys/windows"
)

const (
Expand Down Expand Up @@ -152,7 +153,7 @@ type BCRYPT_PKCS1_PADDING_INFO struct {
pszAlgID *uint16
}

//CRYPTOAPI_BLOB -- https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa381414(v=vs.85)
// CRYPTOAPI_BLOB -- https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa381414(v=vs.85)
type CRYPTOAPI_BLOB struct {
len uint32
data uintptr
Expand Down
9 changes: 9 additions & 0 deletions kms/tpmkms/no_tpmkms.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@

package tpmkms

import (
"context"
"os"
"path/filepath"

"github.com/pkg/errors"
"go.step.sm/crypto/kms/apiv1"
)

func init() {
apiv1.Register(apiv1.TPMKMS, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) {
name := filepath.Base(os.Args[0])
Expand Down
15 changes: 13 additions & 2 deletions sshutil/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,24 @@ func (o *Options) apply(cr CertificateRequest, opts []Option) (*Options, error)
// Option is the type used as a variadic argument in NewCertificate.
type Option func(cr CertificateRequest, o *Options) error

// GetFuncMap returns the list of functions used by the templates. It will
// return all the functions supported by "sprig.TxtFuncMap()" but exclude "env"
// and "expandenv", removed to avoid the leak of information.
func GetFuncMap() template.FuncMap {
return getFuncMap(new(TemplateError))
}

func getFuncMap(err *TemplateError) template.FuncMap {
return templates.GetFuncMap(&err.Message)
}

// WithTemplate is an options that executes the given template text with the
// given data.
func WithTemplate(text string, data TemplateData) Option {
return func(cr CertificateRequest, o *Options) error {
terr := new(TemplateError)
funcMap := templates.GetFuncMap(&terr.Message)

funcMap := getFuncMap(terr)
// Parse template
tmpl, err := template.New("template").Funcs(funcMap).Parse(text)
if err != nil {
return errors.Wrapf(err, "error parsing template")
Expand Down
17 changes: 17 additions & 0 deletions sshutil/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ import (
"testing"
)

func TestGetFuncMap(t *testing.T) {
ok := []string{"fail", "contains", "split"}
fail := []string{"env", "expandenv"}

funcMap := GetFuncMap()
for _, name := range ok {
if _, ok := funcMap[name]; !ok {
t.Errorf("GetFuncMap() does not contain the function %s", name)
}
}
for _, name := range fail {
if _, ok := funcMap[name]; ok {
t.Errorf("GetFuncMap() contains the function %s", name)
}
}
}

func TestWithTemplate(t *testing.T) {
key := mustGeneratePublicKey(t)
cr := CertificateRequest{
Expand Down
35 changes: 28 additions & 7 deletions x509util/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,39 @@ func (o *Options) apply(cr *x509.CertificateRequest, opts []Option) (*Options, e
// Option is the type used as a variadic argument in NewCertificate.
type Option func(cr *x509.CertificateRequest, o *Options) error

// GetFuncMap returns the list of functions used by the templates. It will
// return all the functions supported by "sprig.TxtFuncMap()" but exclude "env"
// and "expandenv", removed to avoid the leak of information. It will also add
// the following functions to encode data using ASN.1:
//
// - asn1Enc: encodes the given string to ASN.1. By default, it will use the
// PrintableString format but it can be change using the suffix ":<format>".
// Supported formats are: "printable", "utf8", "ia5", "numeric", "int", "oid",
// "utc", "generalized", and "raw".
// - asn1Marshal: encodes the given string with the given params using Go's
// asn1.MarshalWithParams.
// - asn1Seq: encodes a sequence of the given ASN.1 data.
// - asn1Set: encodes a set of the given ASN.1 data.
func GetFuncMap() template.FuncMap {
return getFuncMap(new(TemplateError))
}

func getFuncMap(err *TemplateError) template.FuncMap {
funcMap := templates.GetFuncMap(&err.Message)
// asn1 methods
funcMap["asn1Enc"] = asn1Encode
funcMap["asn1Marshal"] = asn1Marshal
funcMap["asn1Seq"] = asn1Sequence
funcMap["asn1Set"] = asn1Set
return funcMap
}

// WithTemplate is an options that executes the given template text with the
// given data.
func WithTemplate(text string, data TemplateData) Option {
return func(cr *x509.CertificateRequest, o *Options) error {
terr := new(TemplateError)
funcMap := templates.GetFuncMap(&terr.Message)
// asn1 methods
funcMap["asn1Enc"] = asn1Encode
funcMap["asn1Marshal"] = asn1Marshal
funcMap["asn1Seq"] = asn1Sequence
funcMap["asn1Set"] = asn1Set

funcMap := getFuncMap(terr)
// Parse template
tmpl, err := template.New("template").Funcs(funcMap).Parse(text)
if err != nil {
Expand Down
20 changes: 20 additions & 0 deletions x509util/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ func createRSACertificateRequest(t *testing.T, bits int, commonName string, sans
return cr, priv
}

func TestGetFuncMap(t *testing.T) {
ok := []string{
"fail", "contains", "split", // generic sprig functions
"asn1Enc", "asn1Marshal", "asn1Seq", "asn1Set", // custom functions
}
fail := []string{"env", "expandenv"}

funcMap := GetFuncMap()
for _, name := range ok {
if _, ok := funcMap[name]; !ok {
t.Errorf("GetFuncMap() does not contain the function %s", name)
}
}
for _, name := range fail {
if _, ok := funcMap[name]; ok {
t.Errorf("GetFuncMap() contains the function %s", name)
}
}
}

func TestWithTemplate(t *testing.T) {
cr, _ := createCertificateRequest(t, "foo", []string{"foo.com", "foo@foo.com", "::1", "https://foo.com"})
crRSA, _ := createRSACertificateRequest(t, 2048, "foo", []string{"foo.com", "foo@foo.com", "::1", "https://foo.com"})
Expand Down