Start working on x5099util unit tests.

This commit is contained in:
Mariano Cano 2020-07-16 19:43:22 -07:00
parent 0de15b0a42
commit 8069d1246b
8 changed files with 792 additions and 6 deletions

View file

@ -0,0 +1,76 @@
package x509util
import (
"crypto/x509"
"reflect"
"testing"
)
func TestSignatureAlgorithm_Set(t *testing.T) {
type args struct {
c *x509.Certificate
}
tests := []struct {
name string
s SignatureAlgorithm
args args
want *x509.Certificate
}{
{"ok", SignatureAlgorithm(x509.ECDSAWithSHA256), args{&x509.Certificate{}}, &x509.Certificate{SignatureAlgorithm: x509.ECDSAWithSHA256}},
{"ok", SignatureAlgorithm(x509.PureEd25519), args{&x509.Certificate{}}, &x509.Certificate{SignatureAlgorithm: x509.PureEd25519}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.s.Set(tt.args.c)
if !reflect.DeepEqual(tt.args.c, tt.want) {
t.Errorf("SignatureAlgorithm.Set() = %v, want %v", tt.args.c, tt.want)
}
})
}
}
func TestSignatureAlgorithm_UnmarshalJSON(t *testing.T) {
type args struct {
data []byte
}
tests := []struct {
name string
args args
want SignatureAlgorithm
wantErr bool
}{
{"MD2_RSA", args{[]byte(`"MD2-RSA"`)}, SignatureAlgorithm(x509.MD2WithRSA), false},
{"MD5-RSA", args{[]byte(`"MD5-RSA"`)}, SignatureAlgorithm(x509.MD5WithRSA), false},
{"SHA1-RSA", args{[]byte(`"SHA1-RSA"`)}, SignatureAlgorithm(x509.SHA1WithRSA), false},
{"SHA256-RSA", args{[]byte(`"SHA256-RSA"`)}, SignatureAlgorithm(x509.SHA256WithRSA), false},
{"SHA384-RSA", args{[]byte(`"SHA384-RSA"`)}, SignatureAlgorithm(x509.SHA384WithRSA), false},
{"SHA512-RSA", args{[]byte(`"SHA512-RSA"`)}, SignatureAlgorithm(x509.SHA512WithRSA), false},
{"SHA256-RSAPSS", args{[]byte(`"SHA256-RSAPSS"`)}, SignatureAlgorithm(x509.SHA256WithRSAPSS), false},
{"SHA384-RSAPSS", args{[]byte(`"SHA384-RSAPSS"`)}, SignatureAlgorithm(x509.SHA384WithRSAPSS), false},
{"SHA512-RSAPSS", args{[]byte(`"SHA512-RSAPSS"`)}, SignatureAlgorithm(x509.SHA512WithRSAPSS), false},
{"DSA-SHA1", args{[]byte(`"DSA-SHA1"`)}, SignatureAlgorithm(x509.DSAWithSHA1), false},
{"DSA-SHA256", args{[]byte(`"DSA-SHA256"`)}, SignatureAlgorithm(x509.DSAWithSHA256), false},
{"ECDSA-SHA1", args{[]byte(`"ECDSA-SHA1"`)}, SignatureAlgorithm(x509.ECDSAWithSHA1), false},
{"ECDSA-SHA256", args{[]byte(`"ECDSA-SHA256"`)}, SignatureAlgorithm(x509.ECDSAWithSHA256), false},
{"ECDSA-SHA384", args{[]byte(`"ECDSA-SHA384"`)}, SignatureAlgorithm(x509.ECDSAWithSHA384), false},
{"ECDSA-SHA512", args{[]byte(`"ECDSA-SHA512"`)}, SignatureAlgorithm(x509.ECDSAWithSHA512), false},
{"Ed25519", args{[]byte(`"Ed25519"`)}, SignatureAlgorithm(x509.PureEd25519), false},
{"lowercase", args{[]byte(`"ecdsa-sha256"`)}, SignatureAlgorithm(x509.ECDSAWithSHA256), false},
{"empty", args{[]byte(`""`)}, SignatureAlgorithm(0), true},
{"unknown", args{[]byte(`"unknown"`)}, SignatureAlgorithm(0), true},
{"null", args{[]byte(`null`)}, SignatureAlgorithm(0), true},
{"number", args{[]byte(`0`)}, SignatureAlgorithm(0), true},
{"object", args{[]byte(`{}`)}, SignatureAlgorithm(0), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var got SignatureAlgorithm
if err := got.UnmarshalJSON(tt.args.data); (err != nil) != tt.wantErr {
t.Errorf("SignatureAlgorithm.UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("SignatureAlgorithm.UnmarshalJSON() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -93,6 +93,7 @@ func (c *Certificate) GetCertificate() *x509.Certificate {
c.AuthorityKeyID.Set(cert)
c.OCSPServer.Set(cert)
c.IssuingCertificateURL.Set(cert)
c.CRLDistributionPoints.Set(cert)
c.PolicyIdentifiers.Set(cert)
if c.BasicConstraints != nil {
c.BasicConstraints.Set(cert)

View file

@ -20,10 +20,6 @@ type CertificateRequest struct {
}
func newCertificateRequest(cr *x509.CertificateRequest) *CertificateRequest {
extensions := make([]Extension, len(cr.Extensions))
for i, e := range cr.Extensions {
extensions[i] = newExtension(e)
}
return &CertificateRequest{
Version: cr.Version,
Subject: newSubject(cr.Subject),
@ -31,7 +27,7 @@ func newCertificateRequest(cr *x509.CertificateRequest) *CertificateRequest {
EmailAddresses: cr.EmailAddresses,
IPAddresses: cr.IPAddresses,
URIs: cr.URIs,
Extensions: extensions,
Extensions: newExtensions(cr.Extensions),
PublicKey: cr.PublicKey,
PublicKeyAlgorithm: cr.PublicKeyAlgorithm,
Signature: cr.Signature,

View file

@ -0,0 +1,212 @@
package x509util
import (
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"net"
"net/url"
"reflect"
"testing"
)
func Test_newCertificateRequest(t *testing.T) {
type args struct {
cr *x509.CertificateRequest
}
tests := []struct {
name string
args args
want *CertificateRequest
}{
{"ok", args{&x509.CertificateRequest{}}, &CertificateRequest{}},
{"complex", args{&x509.CertificateRequest{
Extensions: []pkix.Extension{{Id: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
Subject: pkix.Name{Province: []string{"CA"}, CommonName: "commonName"},
DNSNames: []string{"foo"},
PublicKey: []byte("publicKey"),
}}, &CertificateRequest{
Extensions: []Extension{{ID: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
Subject: Subject{Province: []string{"CA"}, CommonName: "commonName"},
DNSNames: []string{"foo"},
PublicKey: []byte("publicKey"),
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := newCertificateRequest(tt.args.cr); !reflect.DeepEqual(got, tt.want) {
t.Errorf("newCertificateRequest() = %v, want %v", got, tt.want)
}
})
}
}
func TestCertificateRequest_GetCertificate(t *testing.T) {
type fields struct {
Version int
Subject Subject
DNSNames MultiString
EmailAddresses MultiString
IPAddresses MultiIP
URIs MultiURL
Extensions []Extension
PublicKey interface{}
PublicKeyAlgorithm x509.PublicKeyAlgorithm
Signature []byte
SignatureAlgorithm x509.SignatureAlgorithm
}
tests := []struct {
name string
fields fields
want *Certificate
}{
{"ok",
fields{
Version: 2,
Subject: Subject{CommonName: "foo"},
DNSNames: []string{"foo"},
EmailAddresses: []string{"foo@bar.com"},
IPAddresses: []net.IP{net.ParseIP("::1")},
URIs: []*url.URL{{Scheme: "https", Host: "foo.bar"}},
Extensions: []Extension{{ID: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
PublicKey: []byte("publicKey"),
PublicKeyAlgorithm: x509.Ed25519,
Signature: []byte("signature"),
SignatureAlgorithm: x509.PureEd25519,
},
&Certificate{
Subject: Subject{CommonName: "foo"},
DNSNames: []string{"foo"},
EmailAddresses: []string{"foo@bar.com"},
IPAddresses: []net.IP{net.ParseIP("::1")},
URIs: []*url.URL{{Scheme: "https", Host: "foo.bar"}},
Extensions: []Extension{{ID: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
PublicKey: []byte("publicKey"),
PublicKeyAlgorithm: x509.Ed25519,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &CertificateRequest{
Version: tt.fields.Version,
Subject: tt.fields.Subject,
DNSNames: tt.fields.DNSNames,
EmailAddresses: tt.fields.EmailAddresses,
IPAddresses: tt.fields.IPAddresses,
URIs: tt.fields.URIs,
Extensions: tt.fields.Extensions,
PublicKey: tt.fields.PublicKey,
PublicKeyAlgorithm: tt.fields.PublicKeyAlgorithm,
Signature: tt.fields.Signature,
SignatureAlgorithm: tt.fields.SignatureAlgorithm,
}
if got := c.GetCertificate(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("CertificateRequest.GetCertificate() = %v, want %v", got, tt.want)
}
})
}
}
func TestCertificateRequest_GetLeafCertificate(t *testing.T) {
type fields struct {
Version int
Subject Subject
DNSNames MultiString
EmailAddresses MultiString
IPAddresses MultiIP
URIs MultiURL
Extensions []Extension
PublicKey interface{}
PublicKeyAlgorithm x509.PublicKeyAlgorithm
Signature []byte
SignatureAlgorithm x509.SignatureAlgorithm
}
tests := []struct {
name string
fields fields
want *Certificate
}{
{"ok",
fields{
Version: 2,
Subject: Subject{CommonName: "foo"},
DNSNames: []string{"foo"},
EmailAddresses: []string{"foo@bar.com"},
IPAddresses: []net.IP{net.ParseIP("::1")},
URIs: []*url.URL{{Scheme: "https", Host: "foo.bar"}},
Extensions: []Extension{{ID: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
PublicKey: []byte("publicKey"),
PublicKeyAlgorithm: x509.Ed25519,
Signature: []byte("signature"),
SignatureAlgorithm: x509.PureEd25519,
},
&Certificate{
Subject: Subject{CommonName: "foo"},
DNSNames: []string{"foo"},
EmailAddresses: []string{"foo@bar.com"},
IPAddresses: []net.IP{net.ParseIP("::1")},
URIs: []*url.URL{{Scheme: "https", Host: "foo.bar"}},
Extensions: []Extension{{ID: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature),
ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
}),
PublicKey: []byte("publicKey"),
PublicKeyAlgorithm: x509.Ed25519,
},
},
{"rsa",
fields{
Version: 2,
Subject: Subject{CommonName: "foo"},
DNSNames: []string{"foo"},
EmailAddresses: []string{"foo@bar.com"},
IPAddresses: []net.IP{net.ParseIP("::1")},
URIs: []*url.URL{{Scheme: "https", Host: "foo.bar"}},
Extensions: []Extension{{ID: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
PublicKey: &rsa.PublicKey{},
PublicKeyAlgorithm: x509.RSA,
Signature: []byte("signature"),
SignatureAlgorithm: x509.SHA256WithRSA,
},
&Certificate{
Subject: Subject{CommonName: "foo"},
DNSNames: []string{"foo"},
EmailAddresses: []string{"foo@bar.com"},
IPAddresses: []net.IP{net.ParseIP("::1")},
URIs: []*url.URL{{Scheme: "https", Host: "foo.bar"}},
Extensions: []Extension{{ID: []int{1, 2, 3}, Critical: true, Value: []byte{3, 2, 1}}},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment),
ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
}),
PublicKey: &rsa.PublicKey{},
PublicKeyAlgorithm: x509.RSA,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &CertificateRequest{
Version: tt.fields.Version,
Subject: tt.fields.Subject,
DNSNames: tt.fields.DNSNames,
EmailAddresses: tt.fields.EmailAddresses,
IPAddresses: tt.fields.IPAddresses,
URIs: tt.fields.URIs,
Extensions: tt.fields.Extensions,
PublicKey: tt.fields.PublicKey,
PublicKeyAlgorithm: tt.fields.PublicKeyAlgorithm,
Signature: tt.fields.Signature,
SignatureAlgorithm: tt.fields.SignatureAlgorithm,
}
if got := c.GetLeafCertificate(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("CertificateRequest.GetLeafCertificate() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -0,0 +1,224 @@
package x509util
import (
"crypto"
"crypto/ed25519"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"math/big"
"net"
"net/url"
"reflect"
"testing"
)
func createCertificateRequest(t *testing.T, commonName string, sans []string) (*x509.CertificateRequest, crypto.Signer) {
dnsNames, ips, emails, uris := SplitSANs(sans)
t.Helper()
_, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
asn1Data, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
Subject: pkix.Name{CommonName: commonName},
DNSNames: dnsNames,
IPAddresses: ips,
EmailAddresses: emails,
URIs: uris,
SignatureAlgorithm: x509.PureEd25519,
}, priv)
if err != nil {
t.Fatal(err)
}
cr, err := x509.ParseCertificateRequest(asn1Data)
if err != nil {
t.Fatal(err)
}
return cr, priv
}
func TestNewCertificate(t *testing.T) {
cr, priv := createCertificateRequest(t, "commonName", []string{"foo.com"})
crBadSignateure, _ := createCertificateRequest(t, "fail", []string{"foo.com"})
crBadSignateure.PublicKey = priv.Public()
type args struct {
cr *x509.CertificateRequest
opts []Option
}
tests := []struct {
name string
args args
want *Certificate
wantErr bool
}{
{"okSimple", args{cr, nil}, &Certificate{
Subject: Subject{CommonName: "commonName"},
DNSNames: []string{"foo.com"},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature),
ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
}),
Extensions: newExtensions(cr.Extensions),
PublicKey: priv.Public(),
PublicKeyAlgorithm: x509.Ed25519,
}, false},
{"okDefaultTemplate", args{cr, []Option{WithTemplate(DefaultLeafTemplate, CreateTemplateData("commonName", []string{"foo.com"}))}}, &Certificate{
Subject: Subject{CommonName: "commonName"},
SANs: []SubjectAlternativeName{{Type: DNSType, Value: "foo.com"}},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature),
ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
}),
PublicKey: priv.Public(),
PublicKeyAlgorithm: x509.Ed25519,
}, false},
{"badSignature", args{crBadSignateure, nil}, nil, true},
{"failTemplate", args{cr, []Option{WithTemplate(`{{ fail "fatal error }}`, CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true},
{"badJson", args{cr, []Option{WithTemplate(`"this is not a json object"`, CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewCertificate(tt.args.cr, tt.args.opts...)
if (err != nil) != tt.wantErr {
t.Errorf("NewCertificate() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewCertificate() = \n%v, want \n%v", got, tt.want)
}
})
}
}
func TestCertificate_GetCertificate(t *testing.T) {
type fields struct {
Version int
Subject Subject
Issuer Issuer
SerialNumber SerialNumber
DNSNames MultiString
EmailAddresses MultiString
IPAddresses MultiIP
URIs MultiURL
SANs []SubjectAlternativeName
Extensions []Extension
KeyUsage KeyUsage
ExtKeyUsage ExtKeyUsage
SubjectKeyID SubjectKeyID
AuthorityKeyID AuthorityKeyID
OCSPServer OCSPServer
IssuingCertificateURL IssuingCertificateURL
CRLDistributionPoints CRLDistributionPoints
PolicyIdentifiers PolicyIdentifiers
BasicConstraints *BasicConstraints
NameConstaints *NameConstraints
SignatureAlgorithm SignatureAlgorithm
PublicKeyAlgorithm x509.PublicKeyAlgorithm
PublicKey interface{}
}
tests := []struct {
name string
fields fields
want *x509.Certificate
}{
{"ok", fields{
Version: 3,
Subject: Subject{CommonName: "commonName", Organization: []string{"smallstep"}},
Issuer: Issuer{CommonName: "issuer", Organization: []string{"smallstep"}},
SerialNumber: SerialNumber{big.NewInt(123)},
DNSNames: []string{"foo.bar"},
EmailAddresses: []string{"root@foo.com"},
IPAddresses: []net.IP{net.ParseIP("::1")},
URIs: []*url.URL{{Scheme: "mailto", Opaque: "root@foo.com"}},
SANs: []SubjectAlternativeName{
{Type: DNSType, Value: "www.foo.bar"},
{Type: IPType, Value: "127.0.0.1"},
{Type: EmailType, Value: "admin@foo.com"},
{Type: URIType, Value: "mailto:admin@foo.com"},
},
Extensions: []Extension{{ID: []int{1, 2, 3, 4}, Critical: true, Value: []byte("custom extension")}},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature),
ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
}),
SubjectKeyID: []byte("subject-key-id"),
AuthorityKeyID: []byte("authority-key-id"),
OCSPServer: []string{"https://oscp.server"},
IssuingCertificateURL: []string{"https://ca.com"},
CRLDistributionPoints: []string{"https://ca.com/crl"},
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3, 4}},
BasicConstraints: &BasicConstraints{IsCA: true, MaxPathLen: 0},
NameConstaints: &NameConstraints{PermittedDNSDomains: []string{"foo.bar"}},
SignatureAlgorithm: SignatureAlgorithm(x509.PureEd25519),
PublicKeyAlgorithm: x509.Ed25519,
PublicKey: ed25519.PublicKey("public key"),
}, &x509.Certificate{
Version: 0,
Subject: pkix.Name{CommonName: "commonName", Organization: []string{"smallstep"}},
Issuer: pkix.Name{},
SerialNumber: big.NewInt(123),
DNSNames: []string{"foo.bar", "www.foo.bar"},
EmailAddresses: []string{"root@foo.com", "admin@foo.com"},
IPAddresses: []net.IP{net.ParseIP("::1"), net.ParseIP("127.0.0.1")},
URIs: []*url.URL{{Scheme: "mailto", Opaque: "root@foo.com"}, {Scheme: "mailto", Opaque: "admin@foo.com"}},
ExtraExtensions: []pkix.Extension{{Id: []int{1, 2, 3, 4}, Critical: true, Value: []byte("custom extension")}},
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
},
SubjectKeyId: []byte("subject-key-id"),
AuthorityKeyId: []byte("authority-key-id"),
OCSPServer: []string{"https://oscp.server"},
IssuingCertificateURL: []string{"https://ca.com"},
CRLDistributionPoints: []string{"https://ca.com/crl"},
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3, 4}},
IsCA: true,
MaxPathLen: 0,
MaxPathLenZero: true,
BasicConstraintsValid: true,
PermittedDNSDomains: []string{"foo.bar"},
SignatureAlgorithm: x509.PureEd25519,
PublicKeyAlgorithm: x509.Ed25519,
PublicKey: ed25519.PublicKey("public key"),
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Certificate{
Version: tt.fields.Version,
Subject: tt.fields.Subject,
Issuer: tt.fields.Issuer,
SerialNumber: tt.fields.SerialNumber,
DNSNames: tt.fields.DNSNames,
EmailAddresses: tt.fields.EmailAddresses,
IPAddresses: tt.fields.IPAddresses,
URIs: tt.fields.URIs,
SANs: tt.fields.SANs,
Extensions: tt.fields.Extensions,
KeyUsage: tt.fields.KeyUsage,
ExtKeyUsage: tt.fields.ExtKeyUsage,
SubjectKeyID: tt.fields.SubjectKeyID,
AuthorityKeyID: tt.fields.AuthorityKeyID,
OCSPServer: tt.fields.OCSPServer,
IssuingCertificateURL: tt.fields.IssuingCertificateURL,
CRLDistributionPoints: tt.fields.CRLDistributionPoints,
PolicyIdentifiers: tt.fields.PolicyIdentifiers,
BasicConstraints: tt.fields.BasicConstraints,
NameConstaints: tt.fields.NameConstaints,
SignatureAlgorithm: tt.fields.SignatureAlgorithm,
PublicKeyAlgorithm: tt.fields.PublicKeyAlgorithm,
PublicKey: tt.fields.PublicKey,
}
if got := c.GetCertificate(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Certificate.GetCertificate() = \n%+v, want \n%+v", got, tt.want)
}
})
}
}

View file

@ -73,6 +73,19 @@ func newExtension(e pkix.Extension) Extension {
}
}
// newExtensions creates a slice of Extension from a slice of pkix.Exntesion.
func newExtensions(extensions []pkix.Extension) []Extension {
if extensions == nil {
return nil
}
ret := make([]Extension, len(extensions))
for i, e := range extensions {
ret[i] = newExtension(e)
}
return ret
}
// Set adds the extension to the given X509 certificate.
func (e Extension) Set(c *x509.Certificate) {
c.ExtraExtensions = append(c.ExtraExtensions, pkix.Extension{
@ -322,7 +335,7 @@ func (b BasicConstraints) Set(c *x509.Certificate) {
c.BasicConstraintsValid = true
switch {
case b.MaxPathLen == 0:
c.MaxPathLen = b.MaxPathLen
c.MaxPathLen = 0
c.MaxPathLenZero = true
case b.MaxPathLen < 0:
c.MaxPathLen = -1

View file

@ -13,10 +13,14 @@ const (
CertificateRequestKey = "CR"
)
// TemplateError represents an error in a template produced by the fail
// function.
type TemplateError struct {
Message string
}
// Error implements the error interface and returns the error string when a
// template executes the `fail "message"` function.
func (e *TemplateError) Error() string {
return e.Message
}

260
x509util/templates_test.go Normal file
View file

@ -0,0 +1,260 @@
package x509util
import (
"crypto/x509"
"reflect"
"testing"
)
func TestTemplateError_Error(t *testing.T) {
type fields struct {
Message string
}
tests := []struct {
name string
fields fields
want string
}{
{"ok", fields{"an error"}, "an error"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &TemplateError{
Message: tt.fields.Message,
}
if got := e.Error(); got != tt.want {
t.Errorf("TemplateError.Error() = %v, want %v", got, tt.want)
}
})
}
}
func TestNewTemplateData(t *testing.T) {
tests := []struct {
name string
want TemplateData
}{
{"ok", TemplateData{}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewTemplateData(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewTemplateData() = %v, want %v", got, tt.want)
}
})
}
}
func TestCreateTemplateData(t *testing.T) {
type args struct {
commonName string
sans []string
}
tests := []struct {
name string
args args
want TemplateData
}{
{"ok", args{"jane.doe.com", []string{"jane.doe.com", "jane@doe.com", "1.1.1.1", "mailto:jane@doe.com"}}, TemplateData{
SubjectKey: Subject{CommonName: "jane.doe.com"},
SANsKey: []SubjectAlternativeName{
{Type: DNSType, Value: "jane.doe.com"},
{Type: IPType, Value: "1.1.1.1"},
{Type: EmailType, Value: "jane@doe.com"},
{Type: URIType, Value: "mailto:jane@doe.com"},
},
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := CreateTemplateData(tt.args.commonName, tt.args.sans); !reflect.DeepEqual(got, tt.want) {
t.Errorf("CreateTemplateData() = %v, want %v", got, tt.want)
}
})
}
}
func TestTemplateData_SetInsecure(t *testing.T) {
type args struct {
key string
v interface{}
}
tests := []struct {
name string
td TemplateData
args args
want TemplateData
}{
{"empty", TemplateData{}, args{"foo", "bar"}, TemplateData{InsecureKey: TemplateData{"foo": "bar"}}},
{"overwrite", TemplateData{InsecureKey: TemplateData{"foo": "bar"}}, args{"foo", "zar"}, TemplateData{InsecureKey: TemplateData{"foo": "zar"}}},
{"existing", TemplateData{InsecureKey: TemplateData{"foo": "bar"}}, args{"bar", "foo"}, TemplateData{InsecureKey: TemplateData{"foo": "bar", "bar": "foo"}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.td.SetInsecure(tt.args.key, tt.args.v)
if !reflect.DeepEqual(tt.td, tt.want) {
t.Errorf("TemplateData.SetInsecure() = %v, want %v", tt.td, tt.want)
}
})
}
}
func TestTemplateData_SetSubject(t *testing.T) {
type args struct {
v Subject
}
tests := []struct {
name string
td TemplateData
args args
want TemplateData
}{
{"ok", TemplateData{}, args{Subject{CommonName: "foo"}}, TemplateData{SubjectKey: Subject{CommonName: "foo"}}},
{"overwrite", TemplateData{SubjectKey: Subject{CommonName: "foo"}}, args{Subject{Province: []string{"CA"}}}, TemplateData{SubjectKey: Subject{Province: []string{"CA"}}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.td.SetSubject(tt.args.v)
if !reflect.DeepEqual(tt.td, tt.want) {
t.Errorf("TemplateData.SetSubject() = %v, want %v", tt.td, tt.want)
}
})
}
}
func TestTemplateData_SetCommonName(t *testing.T) {
type args struct {
cn string
}
tests := []struct {
name string
td TemplateData
args args
want TemplateData
}{
{"ok", TemplateData{}, args{"commonName"}, TemplateData{SubjectKey: Subject{CommonName: "commonName"}}},
{"overwrite", TemplateData{SubjectKey: Subject{CommonName: "foo", Province: []string{"CA"}}}, args{"commonName"}, TemplateData{SubjectKey: Subject{CommonName: "commonName", Province: []string{"CA"}}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.td.SetCommonName(tt.args.cn)
if !reflect.DeepEqual(tt.td, tt.want) {
t.Errorf("TemplateData.SetCommonName() = %v, want %v", tt.td, tt.want)
}
})
}
}
func TestTemplateData_SetSANs(t *testing.T) {
type args struct {
sans []string
}
tests := []struct {
name string
td TemplateData
args args
want TemplateData
}{
{"ok", TemplateData{}, args{[]string{"jane.doe.com", "jane@doe.com", "1.1.1.1", "mailto:jane@doe.com"}}, TemplateData{
SANsKey: []SubjectAlternativeName{
{Type: DNSType, Value: "jane.doe.com"},
{Type: IPType, Value: "1.1.1.1"},
{Type: EmailType, Value: "jane@doe.com"},
{Type: URIType, Value: "mailto:jane@doe.com"},
}},
},
{"overwrite", TemplateData{}, args{[]string{"jane.doe.com"}}, TemplateData{
SANsKey: []SubjectAlternativeName{
{Type: DNSType, Value: "jane.doe.com"},
}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.td.SetSANs(tt.args.sans)
if !reflect.DeepEqual(tt.td, tt.want) {
t.Errorf("TemplateData.SetSANs() = %v, want %v", tt.td, tt.want)
}
})
}
}
func TestTemplateData_SetToken(t *testing.T) {
type args struct {
v interface{}
}
tests := []struct {
name string
td TemplateData
args args
want TemplateData
}{
{"ok", TemplateData{}, args{"token"}, TemplateData{TokenKey: "token"}},
{"overwrite", TemplateData{TokenKey: "foo"}, args{"token"}, TemplateData{TokenKey: "token"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.td.SetToken(tt.args.v)
if !reflect.DeepEqual(tt.td, tt.want) {
t.Errorf("TemplateData.SetToken() = %v, want %v", tt.td, tt.want)
}
})
}
}
func TestTemplateData_SetUserData(t *testing.T) {
type args struct {
v interface{}
}
tests := []struct {
name string
td TemplateData
args args
want TemplateData
}{
{"ok", TemplateData{}, args{"userData"}, TemplateData{InsecureKey: TemplateData{UserKey: "userData"}}},
{"overwrite", TemplateData{InsecureKey: TemplateData{UserKey: "foo"}}, args{"userData"}, TemplateData{InsecureKey: TemplateData{UserKey: "userData"}}},
{"existing", TemplateData{InsecureKey: TemplateData{"foo": "bar"}}, args{"userData"}, TemplateData{InsecureKey: TemplateData{"foo": "bar", UserKey: "userData"}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.td.SetUserData(tt.args.v)
if !reflect.DeepEqual(tt.td, tt.want) {
t.Errorf("TemplateData.SetUserData() = %v, want %v", tt.td, tt.want)
}
})
}
}
func TestTemplateData_SetCertificateRequest(t *testing.T) {
cr := &x509.CertificateRequest{
DNSNames: []string{"foo", "bar"},
}
cr1 := &CertificateRequest{
DNSNames: []string{"foo", "bar"},
}
cr2 := &CertificateRequest{
EmailAddresses: []string{"foo@bar.com"},
}
type args struct {
cr *x509.CertificateRequest
}
tests := []struct {
name string
td TemplateData
args args
want TemplateData
}{
{"ok", TemplateData{}, args{cr}, TemplateData{InsecureKey: TemplateData{CertificateRequestKey: cr1}}},
{"overwrite", TemplateData{InsecureKey: TemplateData{CertificateRequestKey: cr2}}, args{cr}, TemplateData{InsecureKey: TemplateData{CertificateRequestKey: cr1}}},
{"existing", TemplateData{InsecureKey: TemplateData{"foo": "bar"}}, args{cr}, TemplateData{InsecureKey: TemplateData{"foo": "bar", CertificateRequestKey: cr1}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.td.SetCertificateRequest(tt.args.cr)
if !reflect.DeepEqual(tt.td, tt.want) {
t.Errorf("TemplateData.SetCertificateRequest() = %v, want %v", tt.td, tt.want)
}
})
}
}