rsa/cmd/ca/init.go

87 lines
1.9 KiB
Go

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
}