package ca import ( "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "fmt" "net" "os" "time" "github.com/spf13/cobra" "src.lwithers.me.uk/go/rsa/pkg/ca" ) // Init a new certificate authority from scratch. func Init(cmd *cobra.Command, args []string) { desc := args[0] template := createCATemplate(desc) key, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { fmt.Fprintf(os.Stderr, "Failed to generate new key (%d bits): %v\n", bits, err) os.Exit(1) } _, err = ca.Create(dir, template, key) if err != nil { fmt.Fprintf(os.Stderr, "Failed to initialise new certificate authority: %v\n", err) os.Exit(1) } } func createCATemplate(desc string) *x509.Certificate { from, until := signingDates(30 * 365 * 24 * time.Hour) hasTargetRules := len(permittedDomains) > 0 || len(excludedDomains) > 0 var permittedIP, excludedIP []*net.IPNet if len(permittedIPs) > 0 { hasTargetRules = true for _, ipr := range permittedIPs { permittedIP = append(permittedIP, parseCIDR(ipr)) } } if len(excludedIPs) > 0 { hasTargetRules = true for _, ipr := range permittedIPs { excludedIP = append(excludedIP, parseCIDR(ipr)) } } return &x509.Certificate{ Subject: pkix.Name{ CommonName: desc, }, NotBefore: from, NotAfter: until, BasicConstraintsValid: true, IsCA: true, MaxPathLen: maxPathLen, MaxPathLenZero: (maxPathLen == 0), PermittedDNSDomains: permittedDomains, ExcludedDNSDomains: excludedDomains, PermittedIPRanges: permittedIP, ExcludedIPRanges: excludedIP, PermittedDNSDomainsCritical: hasTargetRules, } } func parseCIDR(s string) *net.IPNet { ip, ipnet, err := net.ParseCIDR(s) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if !ip.Equal(ipnet.IP) { fmt.Fprintf(os.Stderr, "%s: invalid IP range (did you mean %s?)\n", s, ipnet.String()) os.Exit(1) } return ipnet }