Add more tests and missing marshallers.

This commit is contained in:
Mariano Cano 2020-07-20 17:19:20 -07:00
parent aafd6be44a
commit ec5f155f8d
4 changed files with 105 additions and 50 deletions

View file

@ -105,7 +105,7 @@ func (b *badSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts)
} }
func TestNewCertificate(t *testing.T) { func TestNewCertificate(t *testing.T) {
cr, priv := createCertificateRequest(t, "commonName", []string{"foo.com"}) cr, priv := createCertificateRequest(t, "commonName", []string{"foo.com", "root@foo.com"})
crBadSignateure, _ := createCertificateRequest(t, "fail", []string{"foo.com"}) crBadSignateure, _ := createCertificateRequest(t, "fail", []string{"foo.com"})
crBadSignateure.PublicKey = priv.Public() crBadSignateure.PublicKey = priv.Public()
@ -120,9 +120,10 @@ func TestNewCertificate(t *testing.T) {
wantErr bool wantErr bool
}{ }{
{"okSimple", args{cr, nil}, &Certificate{ {"okSimple", args{cr, nil}, &Certificate{
Subject: Subject{CommonName: "commonName"}, Subject: Subject{CommonName: "commonName"},
DNSNames: []string{"foo.com"}, DNSNames: []string{"foo.com"},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature), EmailAddresses: []string{"root@foo.com"},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature),
ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{ ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageClientAuth,
@ -142,8 +143,30 @@ func TestNewCertificate(t *testing.T) {
PublicKey: priv.Public(), PublicKey: priv.Public(),
PublicKeyAlgorithm: x509.Ed25519, PublicKeyAlgorithm: x509.Ed25519,
}, false}, }, false},
{"okExample", args{cr, []Option{WithTemplateFile("./testdata/example.tpl", TemplateData{
SANsKey: []SubjectAlternativeName{
{Type: "dns", Value: "foo.com"},
},
TokenKey: map[string]string{
"Issuer": "https://iss",
"Subject": "sub",
},
})}}, &Certificate{
Subject: Subject{CommonName: "commonName"},
SANs: []SubjectAlternativeName{{Type: DNSType, Value: "foo.com"}},
EmailAddresses: []string{"root@foo.com"},
URIs: []*url.URL{{Scheme: "https", Host: "iss", Fragment: "sub"}},
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}, {"badSignature", args{crBadSignateure, nil}, nil, true},
{"failTemplate", args{cr, []Option{WithTemplate(`{{ fail "fatal error }}`, CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true}, {"failTemplate", args{cr, []Option{WithTemplate(`{{ fail "fatal error }}`, CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true},
{"missingTemplate", args{cr, []Option{WithTemplateFile("./testdata/missing.tpl", 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}, {"badJson", args{cr, []Option{WithTemplate(`"this is not a json object"`, CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true},
} }
for _, tt := range tests { for _, tt := range tests {

View file

@ -40,17 +40,18 @@ func (m *MultiIP) UnmarshalJSON(data []byte) error {
if err != nil { if err != nil {
return err return err
} }
if ms != nil {
ips := make([]net.IP, len(ms)) ips := make([]net.IP, len(ms))
for i, s := range ms { for i, s := range ms {
ip := net.ParseIP(s) ip := net.ParseIP(s)
if ip == nil { if ip == nil {
return errors.Errorf("error unmarshaling json: ip %s is not valid", s) return errors.Errorf("error unmarshaling json: ip %s is not valid", s)
}
ips[i] = ip
} }
ips[i] = ip
}
*m = MultiIP(ips) *m = MultiIP(ips)
}
return nil return nil
} }
@ -58,23 +59,36 @@ func (m *MultiIP) UnmarshalJSON(data []byte) error {
// into a []*net.IPNet. // into a []*net.IPNet.
type MultiIPNet []*net.IPNet type MultiIPNet []*net.IPNet
// MarshalJSON implements the json.Marshaler interface for MultiIPNet.
func (m MultiIPNet) MarshalJSON() ([]byte, error) {
if m == nil {
return []byte("null"), nil
}
ipNets := make([]string, len(m))
for i, v := range m {
ipNets[i] = v.String()
}
return json.Marshal(ipNets)
}
// UnmarshalJSON implements the json.Unmarshaler interface for MultiIPNet. // UnmarshalJSON implements the json.Unmarshaler interface for MultiIPNet.
func (m *MultiIPNet) UnmarshalJSON(data []byte) error { func (m *MultiIPNet) UnmarshalJSON(data []byte) error {
ms, err := unmarshalMultiString(data) ms, err := unmarshalMultiString(data)
if err != nil { if err != nil {
return err return err
} }
if ms != nil {
ipNets := make([]*net.IPNet, len(ms)) ipNets := make([]*net.IPNet, len(ms))
for i, s := range ms { for i, s := range ms {
_, ipNet, err := net.ParseCIDR(s) _, ipNet, err := net.ParseCIDR(s)
if err != nil { if err != nil {
return errors.Wrap(err, "error unmarshaling json") return errors.Wrap(err, "error unmarshaling json")
}
ipNets[i] = ipNet
} }
ipNets[i] = ipNet
}
*m = MultiIPNet(ipNets) *m = MultiIPNet(ipNets)
}
return nil return nil
} }
@ -84,6 +98,9 @@ type MultiURL []*url.URL
// MarshalJSON implements the json.Marshaler interface for MultiURL. // MarshalJSON implements the json.Marshaler interface for MultiURL.
func (m MultiURL) MarshalJSON() ([]byte, error) { func (m MultiURL) MarshalJSON() ([]byte, error) {
if m == nil {
return []byte("null"), nil
}
urls := make([]string, len(m)) urls := make([]string, len(m))
for i, u := range m { for i, u := range m {
urls[i] = u.String() urls[i] = u.String()
@ -97,17 +114,18 @@ func (m *MultiURL) UnmarshalJSON(data []byte) error {
if err != nil { if err != nil {
return err return err
} }
if ms != nil {
urls := make([]*url.URL, len(ms)) urls := make([]*url.URL, len(ms))
for i, s := range ms { for i, s := range ms {
u, err := url.Parse(s) u, err := url.Parse(s)
if err != nil { if err != nil {
return errors.Wrap(err, "error unmarshaling json") return errors.Wrap(err, "error unmarshaling json")
}
urls[i] = u
} }
urls[i] = u
}
*m = MultiURL(urls) *m = MultiURL(urls)
}
return nil return nil
} }
@ -115,6 +133,18 @@ func (m *MultiURL) UnmarshalJSON(data []byte) error {
// of strings into a []asn1.ObjectIdentifier. // of strings into a []asn1.ObjectIdentifier.
type MultiObjectIdentifier []asn1.ObjectIdentifier type MultiObjectIdentifier []asn1.ObjectIdentifier
// MarshalJSON implements the json.Marshaler interface for MultiObjectIdentifier.
func (m MultiObjectIdentifier) MarshalJSON() ([]byte, error) {
if m == nil {
return []byte("null"), nil
}
oids := make([]string, len(m))
for i, u := range m {
oids[i] = u.String()
}
return json.Marshal(oids)
}
// UnmarshalJSON implements the json.Unmarshaler interface for // UnmarshalJSON implements the json.Unmarshaler interface for
// MultiObjectIdentifier. // MultiObjectIdentifier.
func (m *MultiObjectIdentifier) UnmarshalJSON(data []byte) error { func (m *MultiObjectIdentifier) UnmarshalJSON(data []byte) error {
@ -122,17 +152,18 @@ func (m *MultiObjectIdentifier) UnmarshalJSON(data []byte) error {
if err != nil { if err != nil {
return err return err
} }
if ms != nil {
oids := make([]asn1.ObjectIdentifier, len(ms)) oids := make([]asn1.ObjectIdentifier, len(ms))
for i, s := range ms { for i, s := range ms {
oid, err := parseObjectIdentifier(s) oid, err := parseObjectIdentifier(s)
if err != nil { if err != nil {
return err return err
}
oids[i] = oid
} }
oids[i] = oid
}
*m = MultiObjectIdentifier(oids) *m = MultiObjectIdentifier(oids)
}
return nil return nil
} }

View file

@ -11,15 +11,15 @@ import (
// Name is the JSON representation of X.501 type Name, used in the X.509 subject // Name is the JSON representation of X.501 type Name, used in the X.509 subject
// and issuer fields. // and issuer fields.
type Name struct { type Name struct {
Country MultiString `json:"country"` Country MultiString `json:"country,omitempty"`
Organization MultiString `json:"organization"` Organization MultiString `json:"organization,omitempty"`
OrganizationalUnit MultiString `json:"organizationUnit"` OrganizationalUnit MultiString `json:"organizationalUnit,omitempty"`
Locality MultiString `json:"locality"` Locality MultiString `json:"locality,omitempty"`
Province MultiString `json:"province"` Province MultiString `json:"province,omitempty"`
StreetAddress MultiString `json:"streetAddress"` StreetAddress MultiString `json:"streetAddress,omitempty"`
PostalCode MultiString `json:"postalCode"` PostalCode MultiString `json:"postalCode,omitempty"`
SerialNumber string `json:"serialNumber"` SerialNumber string `json:"serialNumber,omitempty"`
CommonName string `json:"commonName"` CommonName string `json:"commonName,omitempty"`
} }
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals a JSON // UnmarshalJSON implements the json.Unmarshal interface and unmarshals a JSON
@ -74,6 +74,7 @@ func (s Subject) Set(c *x509.Certificate) {
// Issuer is the JSON representation of the X.509 issuer field. // Issuer is the JSON representation of the X.509 issuer field.
type Issuer Name type Issuer Name
// nolint:unused
func newIssuer(n pkix.Name) Issuer { func newIssuer(n pkix.Name) Issuer {
return Issuer{ return Issuer{
Country: n.Country, Country: n.Country,

View file

@ -101,7 +101,7 @@ const DefaultLeafTemplate = `{
// can be provided to force only the verified domains, if the option is true // can be provided to force only the verified domains, if the option is true
// `.SANs` will be set with the verified domains. // `.SANs` will be set with the verified domains.
const DefaultIIDLeafTemplate = `{ const DefaultIIDLeafTemplate = `{
"subject": {"commonName": "{{ .Insecure.CR.Subject.CommonName }}"}, "subject": {"commonName":"{{ .Insecure.CR.Subject.CommonName }}"},
{{- if .SANs }} {{- if .SANs }}
"sans": {{ toJson .SANs }}, "sans": {{ toJson .SANs }},
{{- else }} {{- else }}