func parseDN(dn string) *pkix.Name { name := pkix.Name{} matches := dnRegexp.FindAllStringSubmatch(dn, -1) for _, match := range matches { val := match[2] if val == "" { continue } switch match[1] { case "C": name.Country = append(name.Country, val) case "O": name.Organization = append(name.Organization, val) case "OU": name.OrganizationalUnit = append(name.OrganizationalUnit, val) case "L": name.Locality = append(name.Locality, val) case "ST": name.Province = append(name.Province, val) case "SN": name.SerialNumber = val case "CN": name.CommonName = val } } return &name }
func (info *HostCertificateInfo) toName(s string) *pkix.Name { var name pkix.Name for _, pair := range strings.Split(s, ",") { attr := strings.SplitN(pair, "=", 2) if len(attr) != 2 { continue } v := attr[1] switch strings.ToLower(attr[0]) { case "cn": name.CommonName = v case "ou": name.OrganizationalUnit = append(name.OrganizationalUnit, v) case "o": name.Organization = append(name.Organization, v) case "l": name.Locality = append(name.Locality, v) case "st": name.Province = append(name.Province, v) case "c": name.Country = append(name.Country, v) case "emailaddress": name.Names = append(name.Names, pkix.AttributeTypeAndValue{Type: emailAddressOID, Value: v}) } } return &name }
func createBundle(c *cli.Context) { if !c.Args().Present() { cli.ShowSubcommandHelp(c) log.Fatalf("Usage: %v name (common name defaults to name, use --cn and "+ "different name if you need multiple certs for same cn)", c.Command.FullName()) } commonName := strings.Join(c.Args()[:], " ") var filename string if filename = c.String("filename"); len(filename) == 0 { filename = strings.Replace(commonName, " ", "_", -1) filename = strings.Replace(filename, "*", "wildcard", -1) } subject := pkix.Name{CommonName: commonName} if str := c.String("organization"); len(str) > 0 { subject.Organization = []string{str} } if str := c.String("locality"); len(str) > 0 { subject.Locality = []string{str} } if str := c.String("country"); len(str) > 0 { subject.Country = []string{str} } if str := c.String("province"); len(str) > 0 { subject.Province = []string{str} } if str := c.String("organizational-unit"); len(str) > 0 { subject.OrganizationalUnit = []string{str} } template := &x509.Certificate{ Subject: subject, NotAfter: time.Now().AddDate(0, 0, c.Int("expire")), } if c.Bool("ca") { template.IsCA = true filename = "ca" } else if c.Bool("client") { template.ExtKeyUsage = append(template.ExtKeyUsage, x509.ExtKeyUsageClientAuth) template.EmailAddresses = c.StringSlice("email") } else { // We default to server template.ExtKeyUsage = append(template.ExtKeyUsage, x509.ExtKeyUsageServerAuth) IPs := make([]net.IP, 0, len(c.StringSlice("ip"))) for _, ipStr := range c.StringSlice("ip") { if i := net.ParseIP(ipStr); i != nil { IPs = append(IPs, i) } } template.IPAddresses = IPs template.DNSNames = c.StringSlice("dns") } err := easypki.GenerateCertifcate(c.GlobalString("root"), filename, template) if err != nil { log.Fatal(err) } }
func prepareName(name *pkix.Name) { if name.Country == nil { name.StreetAddress = []string{""} name.PostalCode = []string{""} name.Province = []string{""} name.Locality = []string{""} name.OrganizationalUnit = []string{""} name.Organization = []string{""} name.Country = []string{""} } }
func Unmarshal(dn string) (pkix.Name, error) { var output pkix.Name segments := strings.Split(dn, ",") for segment := range segments { identifier := strings.SplitN(segments[segment], "=", 2) if identifier[0] == "CN" { output.CommonName = identifier[1] } else if identifier[0] == "C" { output.Country = append(output.Country, identifier[1]) } else if identifier[0] == "L" { output.Locality = append(output.Locality, identifier[1]) } else if identifier[0] == "ST" { output.Province = append(output.Province, identifier[1]) } else if identifier[0] == "SA" { output.StreetAddress = append(output.StreetAddress, identifier[1]) } else if identifier[0] == "O" { output.Organization = append(output.Organization, identifier[1]) } else if identifier[0] == "OU" { output.OrganizationalUnit = append(output.OrganizationalUnit, identifier[1]) } } return output, nil }
// Name returns the subject info as a PKIX name strucutre for a // certificate. func (si *SubjectInfo) Name() pkix.Name { var name pkix.Name if si.Country != "" { name.Country = []string{si.Country} } if si.OrgName != "" { name.Organization = []string{si.OrgName} } if si.OrgUnitName != "" { name.OrganizationalUnit = []string{si.OrgUnitName} } if si.Locality != "" { name.Locality = []string{si.Locality} } if si.StateOrProvince != "" { name.Province = []string{si.StateOrProvince} } if si.CommonName != "" { name.CommonName = si.CommonName } if si.Email != "" { name.Names = []pkix.AttributeTypeAndValue{ pkix.AttributeTypeAndValue{ Type: asn1EmailAddress, Value: si.Email, }, } } return name }
func certNew(argv map[string]interface{}) (err error) { // TODO - this whole function needs to be refactored name := ArgString(argv["<name>"], nil) exportFile := ArgString(argv["--export"], nil) expiry := ArgInt(argv["--expiry"], 365) caName := ArgString(argv["--ca"], "") dnLocality := ArgString(argv["--dn-l"], "") dnState := ArgString(argv["--dn-st"], "") dnOrg := ArgString(argv["--dn-o"], "") dnOrgUnit := ArgString(argv["--dn-ou"], "") dnCountry := ArgString(argv["--dn-c"], "") dnStreet := ArgString(argv["--dn-street"], "") dnPostal := ArgString(argv["--dn-postal"], "") // TODO - This should really be in a certificate function subject := pkix.Name{CommonName: name} if dnLocality != "" { subject.Locality = []string{dnLocality} } if dnState != "" { subject.Province = []string{dnState} } if dnOrg != "" { subject.Organization = []string{dnOrg} } if dnOrgUnit != "" { subject.OrganizationalUnit = []string{dnOrgUnit} } if dnCountry != "" { subject.Country = []string{dnCountry} } if dnStreet != "" { subject.StreetAddress = []string{dnStreet} } if dnPostal != "" { subject.PostalCode = []string{dnPostal} } cert, err := x509.NewCertificate(nil) checkAppFatal("Couldn't create new certificate: %s", err) cert.Data.Body.Name = name cert.Data.Body.Expiry = expiry var files []ExportFile certFile := fmt.Sprintf("%s-cert.pem", cert.Data.Body.Name) keyFile := fmt.Sprintf("%s-key.pem", cert.Data.Body.Name) caFile := fmt.Sprintf("%s-cacert.pem", cert.Data.Body.Name) if caName == "" { // Self-signed err := cert.Generate(nil, &subject) checkAppFatal("Couldn't generate certificate: %s", err) files = append(files, ExportFile{Name: caFile, Mode: 0644, Content: []byte(cert.Data.Body.Certificate)}) } else { app := NewAdminApp() app.Load() app.LoadOrgIndex() caId, err := app.index.org.GetCA(caName) checkUserFatal("Couldn't find CA '%s'%.0s", caName, err) caContainerJson, err := app.fs.api.GetPrivate(app.entities.org.Data.Body.Id, caId) caContainer, err := document.NewContainer(caContainerJson) checkAppFatal("Couldn't create container from json: %s", err) caJson, err := app.entities.org.VerifyThenDecrypt(caContainer) checkAppFatal("Couldn't verify and decrypt ca container: %s", err) ca, err := x509.NewCA(caJson) checkAppFatal("Couldn't create ca: %s", err) err = cert.Generate(ca, &subject) checkAppFatal("Couldn't generate certificate: %s", err) files = append(files, ExportFile{Name: caFile, Mode: 0644, Content: []byte(ca.Data.Body.Certificate)}) } files = append(files, ExportFile{Name: certFile, Mode: 0644, Content: []byte(cert.Data.Body.Certificate)}) files = append(files, ExportFile{Name: keyFile, Mode: 0600, Content: []byte(cert.Data.Body.PrivateKey)}) if caName == "" { } else { } logger.Infof("Export to '%s'", exportFile) Export(files, exportFile) return nil }
func (cont *CSRController) New(params *CSRParams) (*x509.CSR, error) { logger.Debug("creating new CSR") logger.Tracef("received params: %s", params) if err := params.ValidateName(true); err != nil { return nil, err } if err := cont.env.LoadAdminEnv(); err != nil { return nil, err } // TODO - This should really be in a CSR function subject := pkix.Name{CommonName: *params.Name} if *params.DnLocality != "" { subject.Locality = []string{*params.DnLocality} } if *params.DnState != "" { subject.Province = []string{*params.DnState} } if *params.DnOrg != "" { subject.Organization = []string{*params.DnOrg} } if *params.DnOrgUnit != "" { subject.OrganizationalUnit = []string{*params.DnOrgUnit} } if *params.DnCountry != "" { subject.Country = []string{*params.DnCountry} } if *params.DnStreet != "" { subject.StreetAddress = []string{*params.DnStreet} } if *params.DnPostal != "" { subject.PostalCode = []string{*params.DnPostal} } logger.Debug("creating CSR struct") csr, err := x509.NewCSR(nil) if err != nil { return nil, err } csr.Data.Body.Id = x509.NewID() csr.Data.Body.Name = *params.Name if *params.CsrFile == "" && *params.KeyFile == "" { csr.Data.Body.KeyType = *params.KeyType logger.Debug("generating CSR and key") csr.Generate(&subject) } else { if *params.CsrFile == "" { return nil, fmt.Errorf("CSR PEM file must be provided if importing") } logger.Debugf("importing CSR from '%s'", *params.CsrFile) ok, err := fs.Exists(*params.CsrFile) if err != nil { return nil, err } if !ok { logger.Warnf("CSR file '%s' does not exist", *params.CsrFile) logger.Tracef("returning nil error") return nil, nil } logger.Debug("reading file") csrPem, err := fs.ReadFile(*params.CsrFile) if err != nil { return nil, err } logger.Debug("decoding CSR PEM") _, err = x509.PemDecodeX509CSR([]byte(csrPem)) if err != nil { return nil, err } csr.Data.Body.CSR = csrPem if *params.KeyFile != "" { logger.Debugf("importing private key file from '%s'", *params.KeyFile) ok, err := fs.Exists(*params.KeyFile) if err != nil { return nil, err } if !ok { logger.Warnf("key file '%s' does not exist", *params.KeyFile) logger.Trace("returning nil error") return nil, nil } logger.Debugf("reading key file") keyPem, err := fs.ReadFile(*params.KeyFile) if err != nil { return nil, err } logger.Debug("decoding private key PEM") key, err := crypto.PemDecodePrivate([]byte(keyPem)) if err != nil { return nil, err } keyType, err := crypto.GetKeyType(key) if err != nil { return nil, err } csr.Data.Body.KeyType = string(keyType) csr.Data.Body.PrivateKey = keyPem } } if *params.StandaloneFile == "" { err = cont.SaveCSR(csr) if err != nil { return nil, err } var tags string if *params.Tags == "NAME" { tags = *params.Name } else { tags = *params.Tags } err = cont.AddCSRToOrgIndex(csr, tags) if err != nil { return nil, err } } return csr, nil }
func (cont *CertificateController) New(params *CertificateParams) (*x509.Certificate, *x509.CA, error) { logger.Debug("creating new certificate") logger.Tracef("received params: %s", params) if err := params.ValidateName(true); err != nil { return nil, nil, err } if err := cont.env.LoadAdminEnv(); err != nil { return nil, nil, err } // TODO - This should really be in a certificate function subject := pkix.Name{CommonName: *params.Name} if *params.DnLocality != "" { subject.Locality = []string{*params.DnLocality} } if *params.DnState != "" { subject.Province = []string{*params.DnState} } if *params.DnOrg != "" { subject.Organization = []string{*params.DnOrg} } if *params.DnOrgUnit != "" { subject.OrganizationalUnit = []string{*params.DnOrgUnit} } if *params.DnCountry != "" { subject.Country = []string{*params.DnCountry} } if *params.DnStreet != "" { subject.StreetAddress = []string{*params.DnStreet} } if *params.DnPostal != "" { subject.PostalCode = []string{*params.DnPostal} } logger.Debug("creating certificate struct") cert, err := x509.NewCertificate(nil) if err != nil { return nil, nil, err } cert.Data.Body.Name = *params.Name cert.Data.Body.Expiry = *params.Expiry var ca *x509.CA if *params.CertFile == "" && *params.KeyFile == "" { cert.Data.Body.KeyType = *params.KeyType logger.Debug("generating certificate and key") if *params.Ca == "" { if err := cert.Generate(nil, &subject); err != nil { return nil, nil, err } } else { index, err := cont.env.controllers.org.GetIndex() if err != nil { return nil, nil, err } caId, err := index.GetCA(*params.Ca) if err != nil { return nil, nil, err } ca, err = cont.GetCA(caId) if err != nil { return nil, nil, err } logger.Debugf("generating certificate and signing with CA '%s'", caId) if err := cert.Generate(ca, &subject); err != nil { return nil, nil, err } } } else { if *params.CertFile == "" { return nil, nil, fmt.Errorf("certificate PEM file must be provided if importing") } logger.Debugf("importing certificate from '%s'", *params.CertFile) ok, err := fs.Exists(*params.CertFile) if err != nil { return nil, nil, err } if !ok { logger.Warnf("certificate file '%s' does not exist", *params.CertFile) return nil, nil, nil } logger.Debug("reading certificate from file") certPem, err := fs.ReadFile(*params.CertFile) if err != nil { return nil, nil, err } logger.Debug("decoding certificate PEM") importCert, err := x509.PemDecodeX509Certificate([]byte(certPem)) if err != nil { return nil, nil, err } cert.Data.Body.Id = x509.NewID() cert.Data.Body.Certificate = certPem certExpiry := int(importCert.NotAfter.Sub(importCert.NotBefore) / (time.Hour * 24)) cert.Data.Body.Expiry = certExpiry if *params.KeyFile != "" { logger.Debugf("importing certificate privte key from '%s'", *params.KeyFile) ok, err := fs.Exists(*params.KeyFile) if err != nil { return nil, nil, err } if !ok { logger.Warnf("key file '%s' does not exist", *params.KeyFile) return nil, nil, nil } logger.Debug("reading private key file") keyPem, err := fs.ReadFile(*params.KeyFile) if err != nil { return nil, nil, err } logger.Debug("decoding private key PEM") key, err := crypto.PemDecodePrivate([]byte(keyPem)) if err != nil { return nil, nil, err } logger.Debug("getting key type") keyType, err := crypto.GetKeyType(key) if err != nil { return nil, nil, err } cert.Data.Body.KeyType = string(keyType) cert.Data.Body.PrivateKey = keyPem } } if *params.StandaloneFile == "" { err = cont.SaveCert(cert) if err != nil { return nil, nil, err } var tags string if *params.Tags == "NAME" { tags = *params.Name } else { tags = *params.Tags } err = cont.AddCertToOrgIndex(cert, tags) if err != nil { return nil, nil, err } } logger.Trace("returning certificate") return cert, ca, nil }