114 lines
3.2 KiB
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.Fprintln(os.Stderr, "--valid-from %s: not a valid RFC3339-format timestamp\n")
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
}
|
||
|
if validUntil == "" {
|
||
|
until = time.Now().Add(defaultDuration)
|
||
|
} else {
|
||
|
until, err = time.Parse(time.RFC3339, validUntil)
|
||
|
if err != nil {
|
||
|
fmt.Fprintln(os.Stderr, "--valid-until %s: not a valid RFC3339-format timestamp\n")
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|