diff --git a/authority/config/config.go b/authority/config/config.go index fabd3f91..4d7592ac 100644 --- a/authority/config/config.go +++ b/authority/config/config.go @@ -75,6 +75,7 @@ type ASN1DN struct { Locality string `json:"locality,omitempty"` Province string `json:"province,omitempty"` StreetAddress string `json:"streetAddress,omitempty"` + SerialNumber string `json:"serialNumber,omitempty"` CommonName string `json:"commonName,omitempty"` } diff --git a/authority/export.go b/authority/export.go index f78f7fbb..316ede0e 100644 --- a/authority/export.go +++ b/authority/export.go @@ -4,6 +4,7 @@ import ( "encoding/json" "io/ioutil" "net/url" + "path/filepath" "strings" "github.com/pkg/errors" @@ -20,26 +21,34 @@ func (a *Authority) Export() (c *config.Configuration, err error) { } }() + files := make(map[string][]byte) c = &config.Configuration{ - Root: mustReadFilesOrUris(a.config.Root), - FederatedRoots: mustReadFilesOrUris(a.config.FederatedRoots), - Intermediate: mustReadFileOrUri(a.config.IntermediateCert), - IntermediateKey: mustReadFileOrUri(a.config.IntermediateKey), + Version: "1.0", + Root: mustReadFilesOrUris(a.config.Root, files), + FederatedRoots: mustReadFilesOrUris(a.config.FederatedRoots, files), + Intermediate: mustReadFileOrUri(a.config.IntermediateCert, files), + IntermediateKey: mustReadFileOrUri(a.config.IntermediateKey, files), Address: a.config.Address, InsecureAddress: a.config.InsecureAddress, DnsNames: a.config.DNSNames, Db: mustMarshalToStruct(a.config.DB), Logger: mustMarshalToStruct(a.config.Logger), Monitoring: mustMarshalToStruct(a.config.Monitoring), - Authority: &config.Authority{}, - Password: mustPassword(a.config.Password), + Authority: &config.Authority{ + Id: a.config.AuthorityConfig.AuthorityID, + EnableAdmin: a.config.AuthorityConfig.EnableAdmin, + DisableIssuedAtCheck: a.config.AuthorityConfig.DisableIssuedAtCheck, + Backdate: a.config.AuthorityConfig.Backdate.String(), + }, + Password: mustPassword(a.config.Password), + Files: files, } // SSH if v := a.config.SSH; v != nil { c.Ssh = &config.SSH{ - HostKey: mustReadFileOrUri(v.HostKey), - UserKey: mustReadFileOrUri(v.UserKey), + HostKey: mustReadFileOrUri(v.HostKey, files), + UserKey: mustReadFileOrUri(v.UserKey, files), AddUserPrincipal: v.AddUserPrincipal, AddUserCommand: v.AddUserCommand, } @@ -80,8 +89,6 @@ func (a *Authority) Export() (c *config.Configuration, err error) { } // Authority - c.Authority.Id = a.config.AuthorityConfig.AuthorityID - // cas options if v := a.config.AuthorityConfig.Options; v != nil { c.Authority.Type = 0 @@ -96,13 +103,12 @@ func (a *Authority) Export() (c *config.Configuration, err error) { c.Authority.CertificateIssuer = &config.CertificateIssuer{ Type: config.CertificateIssuer_Type(typ), Provisioner: iss.Provisioner, - Certificate: mustReadFileOrUri(iss.Certificate), - Key: mustReadFileOrUri(iss.Key), + Certificate: mustReadFileOrUri(iss.Certificate, files), + Key: mustReadFileOrUri(iss.Key, files), Password: mustPassword(iss.Password), } } } - // admins for { list, cursor := a.admins.Find("", 100) @@ -111,7 +117,6 @@ func (a *Authority) Export() (c *config.Configuration, err error) { break } } - // provisioners for { list, cursor := a.provisioners.Find("", 100) @@ -126,7 +131,21 @@ func (a *Authority) Export() (c *config.Configuration, err error) { break } } + // global claims c.Authority.Claims = claimsToLinkedca(a.config.AuthorityConfig.Claims) + // Distiguised names template + if v := a.config.AuthorityConfig.Template; v != nil { + c.Authority.Template = &config.DistinguishedName{ + Country: v.Country, + Organization: v.Organization, + OrganizationalUnit: v.OrganizationalUnit, + Locality: v.Locality, + Province: v.Province, + StreetAddress: v.StreetAddress, + SerialNumber: v.SerialNumber, + CommonName: v.CommonName, + } + } // TLS if v := a.config.TLS; v != nil { @@ -155,18 +174,14 @@ func (a *Authority) Export() (c *config.Configuration, err error) { if !ok { return nil, errors.Errorf("unsupported template type %s", t.Type) } - content := t.Content - if len(content) == 0 { - content = mustReadFileOrUri(t.TemplatePath) - } c.Templates.Ssh.Hosts = append(c.Templates.Ssh.Hosts, &config.Template{ Type: config.Template_Type(typ), Name: t.Name, - Template: t.TemplatePath, + Template: mustReadFileOrUri(t.TemplatePath, files), Path: t.Path, Comment: t.Comment, Requires: t.RequiredData, - Content: content, + Content: t.Content, }) } for _, t := range v.SSH.User { @@ -174,18 +189,14 @@ func (a *Authority) Export() (c *config.Configuration, err error) { if !ok { return nil, errors.Errorf("unsupported template type %s", t.Type) } - content := t.Content - if len(content) == 0 { - content = mustReadFileOrUri(t.TemplatePath) - } c.Templates.Ssh.Users = append(c.Templates.Ssh.Users, &config.Template{ Type: config.Template_Type(typ), Name: t.Name, - Template: t.TemplatePath, + Template: mustReadFileOrUri(t.TemplatePath, files), Path: t.Path, Comment: t.Comment, Requires: t.RequiredData, - Content: content, + Content: t.Content, }) } } @@ -212,11 +223,18 @@ func mustMarshalToStruct(v interface{}) *structpb.Struct { return r } -func mustReadFileOrUri(fn string) []byte { +func mustReadFileOrUri(fn string, m map[string][]byte) string { if fn == "" { - return nil + return "" } + stepPath := filepath.ToSlash(step.StepPath()) + if !strings.HasSuffix(stepPath, "/") { + stepPath += "/" + } + + fn = strings.TrimPrefix(filepath.ToSlash(fn), stepPath) + ok, err := isFilename(fn) if err != nil { panic(err) @@ -226,15 +244,16 @@ func mustReadFileOrUri(fn string) []byte { if err != nil { panic(errors.Wrapf(err, "error reading %s", fn)) } - return b + m[fn] = b + return fn } - return []byte(fn) + return fn } -func mustReadFilesOrUris(fns []string) [][]byte { - var result [][]byte +func mustReadFilesOrUris(fns []string, m map[string][]byte) []string { + var result []string for _, fn := range fns { - result = append(result, mustReadFileOrUri(fn)) + result = append(result, mustReadFileOrUri(fn, m)) } return result } diff --git a/authority/tls.go b/authority/tls.go index b2dc4c92..32d6f3c6 100644 --- a/authority/tls.go +++ b/authority/tls.go @@ -36,7 +36,6 @@ func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc { if def == nil { return errors.New("default ASN1DN template cannot be nil") } - if len(crt.Subject.Country) == 0 && def.Country != "" { crt.Subject.Country = append(crt.Subject.Country, def.Country) } @@ -55,7 +54,12 @@ func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc { if len(crt.Subject.StreetAddress) == 0 && def.StreetAddress != "" { crt.Subject.StreetAddress = append(crt.Subject.StreetAddress, def.StreetAddress) } - + if len(crt.Subject.SerialNumber) == 0 && def.SerialNumber != "" { + crt.Subject.SerialNumber = def.SerialNumber + } + if len(crt.Subject.CommonName) == 0 && def.CommonName != "" { + crt.Subject.CommonName = def.CommonName + } return nil } }