rsa/cmd/ca/ca.go

114 lines
3.2 KiB
Go

package ca
import (
"fmt"
"os"
"time"
"github.com/spf13/cobra"
)
var (
dir string
outputFilename string
// signCommonFlags refers to these
validFrom string
validUntil string
// createCACommonFlags refers to these
bits int
excludedDomains []string
excludedIPs []string
maxPathLen int
permittedDomains []string
permittedIPs []string
)
// Register the "keygen" subcommand.
func Register(root *cobra.Command) {
caCmd := &cobra.Command{
Use: "ca",
Short: "Certificate authority creation and operation",
}
caCmd.PersistentFlags().StringVarP(&dir, "dir", "d", "", "Directory holding CA")
caCmd.MarkPersistentFlagRequired("dir")
root.AddCommand(caCmd)
// init command
cmd := &cobra.Command{
Use: "init <description>",
Short: "Initialise a brand-new certificate authority",
Args: cobra.ExactArgs(1),
Run: Init,
}
createCACommonFlags(cmd)
signCommonFlags(cmd)
caCmd.AddCommand(cmd)
// sign command
cmd = &cobra.Command{
Use: "sign csr.pem",
Short: "Sign one or more CSRs",
Args: cobra.ExactArgs(1),
Run: Sign,
}
cmd.Flags().StringVarP(&outputFilename, "output", "o", "", "Name of output file (default stdout).")
signCommonFlags(cmd)
caCmd.AddCommand(cmd)
// intermediate command
cmd = &cobra.Command{
Use: "intermediate <dir> <description>",
Short: "Using an existing CA, create a new intermediate CA",
Args: cobra.ExactArgs(2),
Run: Intermediate,
}
createCACommonFlags(cmd)
signCommonFlags(cmd)
caCmd.AddCommand(cmd)
}
func createCACommonFlags(cmd *cobra.Command) {
cmd.Flags().IntVarP(&bits, "bits", "b", 3072, "Key size in bits")
cmd.Flags().StringSliceVar(&excludedDomains, "exclude-domain", nil,
"Do not allow certs to be issued for named domain. Multiple may be specified")
cmd.Flags().StringSliceVar(&excludedIPs, "exclude-cidr", nil,
"Do not allow certs to be issued for given IP range. Multiple may be specified")
cmd.Flags().IntVar(&maxPathLen, "max-path-len", -1,
"Maximum path length (whether any further CAs may be issued)")
cmd.Flags().StringSliceVar(&permittedDomains, "permit-domain", nil,
"Allow certs to be issued only for named domain. Multiple may be specified")
cmd.Flags().StringSliceVar(&permittedIPs, "permit-cidr", nil,
"Allow certs to be issued only for given IP range. Multiple may be specified")
}
func signCommonFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&validFrom, "valid-from", "", "RFC3339-format timestamp for start of cert validity")
cmd.Flags().StringVar(&validUntil, "valid-until", "", "RFC3339-format timestamp for end of cert validity")
}
func signingDates(defaultDuration time.Duration) (from, until time.Time) {
var err error
if validFrom == "" {
from = time.Now().Add(-2 * time.Hour)
} else {
from, err = time.Parse(time.RFC3339, validFrom)
if err != nil {
fmt.Fprintf(os.Stderr, "--valid-from %q: not a valid RFC3339-format timestamp\n", validFrom)
os.Exit(1)
}
}
if validUntil == "" {
until = time.Now().Add(defaultDuration)
} else {
until, err = time.Parse(time.RFC3339, validUntil)
if err != nil {
fmt.Fprintf(os.Stderr, "--valid-until %q: not a valid RFC3339-format timestamp\n", validUntil)
os.Exit(1)
}
}
return
}