-
Notifications
You must be signed in to change notification settings - Fork 0
/
csr.go
90 lines (78 loc) · 2.74 KB
/
csr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package main
import (
"fmt"
"github.com/drognisep/certserver/business"
"github.com/spf13/pflag"
"io/ioutil"
"net"
"os"
)
func createCsr(command string, args []string) {
flags := pflag.NewFlagSet(command, pflag.ExitOnError)
flags.Usage = func() {
fmt.Printf(`'%[1]s' creates a new DER encoded Certificate Signing Request with the given details.
Usage: %[1]s [FLAGS] COMMON_NAME
COMMON_NAME:
The "CN" field in the certificate. This could be a domain name or another identifying string.
If spaces are desired, ensure that they're escaped or grouped properly.
Flags:
%s`, command, flags.FlagUsages())
}
var (
commonName string
csrPath string
keyPath string
sans []string
ips []net.IP
clientCert bool
)
flags.StringVar(&csrPath, "csr-out", "", "Specifies a different output path for the CSR. Default is './<common-name>.csr'.")
flags.StringVar(&keyPath, "key-out", "", "Specifies a different output path for the private key. Default is './<common-name>.key'.")
flags.StringSliceVar(&sans, "san", nil, "Specifies a Subject Alternative Name used for this CSR. At least one of 'san' or 'ip' must be specified, unless 'is-client' is specified.")
flags.IPSliceVar(&ips, "ip", nil, "Specifies an IP used for this CSR. At least one of 'san' or 'ip' must be specified, unless 'is-client' is specified.")
flags.BoolVar(&clientCert, "is-client", false, "Specifies that this CSR is for client authentication, so no SAN or IP will be allowed")
if err := flags.Parse(args); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if flags.NArg() < 1 {
fmt.Println("Must pass the common name as an argument")
flags.Usage()
os.Exit(1)
}
commonName = flags.Arg(0)
if csrPath == "" {
csrPath = commonName + ".csr"
}
if keyPath == "" {
keyPath = commonName + ".key"
}
if len(sans) == 0 && len(ips) == 0 && !clientCert {
fmt.Println("At least one IP and/or SAN must be specified")
flags.Usage()
os.Exit(1)
} else if clientCert && (len(sans) > 0 || len(ips) > 0) {
fmt.Println("No SAN or IP is allowed for client authentication")
flags.Usage()
os.Exit(1)
}
var opts []business.CsrOpt
for _, san := range sans {
opts = append(opts, business.CsrAddSan(san))
}
for _, ip := range ips {
opts = append(opts, business.CsrAddIP(ip))
}
name, err := business.PromptCertNameDetails()
if err != nil {
fmt.Printf("Error getting certificate details: %v\n", err)
os.Exit(1)
}
csr, priv, err := business.NewGeneratedCsr(commonName, name, opts...)
if err := ioutil.WriteFile(csrPath, csr, 0600); err != nil {
fmt.Printf("Failed to write CSR to file '%s': %v\n", csrPath, err)
}
if err := ioutil.WriteFile(keyPath, priv, 0600); err != nil {
fmt.Printf("Failed to write private key to file '%s': %v\n", keyPath, err)
}
}