@@ -26,7 +26,6 @@ import (
2626 "crypto/rsa"
2727 "crypto/tls"
2828 "crypto/x509"
29- "encoding/pem"
3029 "flag"
3130 "fmt"
3231 "net"
@@ -39,17 +38,22 @@ import (
3938)
4039
4140func main () {
42- var caPath , caKeyPath , dest , name , ipList , prefix , pass string
43- var rsaflag bool
41+ var caPath , caKeyPath , dest , name , names , ipList , prefix , pass string
42+ var client , rsaflag , noip bool
4443 flag .StringVar (& caPath , "ca" , "" ,
4544 "File path for CA in PEM format" )
4645 flag .StringVar (& caKeyPath , "ca-key" , "" ,
4746 "File path for the CA key in PEM format" )
48- flag .BoolVar (& rsaflag , "rsaflag" , false ,
49- "" )
50- // TODO: accept multiple DNS names
47+ flag .BoolVar (& rsaflag , "rsa" , false ,
48+ "generate a RSA with a 2048-bit key certificate" )
49+ flag .BoolVar (& client , "client" , false ,
50+ "generates a client certificate without any IP or SAN/DNS" )
5151 flag .StringVar (& name , "name" , "localhost" ,
52- "used as \" distinguished name\" and \" Subject Alternate Name values\" for the child certificate" )
52+ "a single \" Subject Alternate Name values\" for the child certificate. It's added to 'names' if set" )
53+ flag .StringVar (& names , "names" , "" ,
54+ "a comma separated list of \" Subject Alternate Name values\" for the child certificate" )
55+ flag .BoolVar (& noip , "noip" , false ,
56+ "generate a certificate with no IP. It overrides -ips." )
5357 flag .StringVar (& ipList , "ips" , "127.0.0.1" ,
5458 "a comma separated list of IP addresses for the child certificate" )
5559 flag .StringVar (& prefix , "prefix" , "current timestamp" ,
@@ -76,10 +80,17 @@ func main() {
7680 }
7781 fmt .Println ("files will be witten to:" , wd )
7882
79- ips := strings .Split (ipList , "," )
8083 var netIPs []net.IP
81- for _ , ip := range ips {
82- netIPs = append (netIPs , net .ParseIP (ip ))
84+ if ! noip {
85+ ips := strings .Split (ipList , "," )
86+ for _ , ip := range ips {
87+ netIPs = append (netIPs , net .ParseIP (ip ))
88+ }
89+ }
90+
91+ var dnsNames []string
92+ if names != "" {
93+ dnsNames = strings .Split (names , "," )
8394 }
8495
8596 rootCert , rootKey := getCA (rsaflag , caPath , caKeyPath , dest , prefix )
@@ -92,48 +103,35 @@ func main() {
92103 pub ,
93104 rootKey ,
94105 rootCert ,
95- certutil .WithCNPrefix (prefix ))
106+ certutil .WithCNPrefix (prefix ),
107+ certutil .WithDNSNames (dnsNames ... ),
108+ certutil .WithClientCert (client ))
96109 if err != nil {
97110 panic (fmt .Errorf ("error generating child certificate: %w" , err ))
98111 }
99112
100- savePair (dest , filePrefix + name , childPair )
101-
102- if pass == "" {
103- return
104- }
105-
106- fmt .Printf ("passphrase present, encrypting \" %s\" certificate key\n " ,
107- name )
108- err = os .WriteFile (filePrefix + name + "-passphrase" , []byte (pass ), 0o600 )
109- if err != nil {
110- panic (fmt .Errorf ("error writing passphrase file: %w" , err ))
111- }
112-
113- key , err := x509 .MarshalPKCS8PrivateKey (childCert .PrivateKey )
114- if err != nil {
115- panic (fmt .Errorf ("error getting ecdh.PrivateKey from the child's private key: %w" , err ))
113+ if client {
114+ name = "client"
116115 }
116+ savePair (dest , filePrefix + name , childPair )
117117
118- blockType := "EC PRIVATE KEY"
119- if rsaflag {
120- blockType = "RSA PRIVATE KEY"
121- }
122- encPem , err := x509 .EncryptPEMBlock ( //nolint:staticcheck // we need to drop support for this, but while we don't, it needs to be tested.
123- rand .Reader ,
124- blockType ,
125- key ,
126- []byte (pass ),
127- x509 .PEMCipherAES128 )
128- if err != nil {
129- panic (fmt .Errorf ("failed encrypting agent child certificate key block: %v" , err ))
130- }
118+ if pass != "" {
119+ fmt .Printf ("passphrase present, encrypting \" %s\" certificate key\n " ,
120+ name )
121+ err = os .WriteFile (filePrefix + name + "-passphrase" , []byte (pass ), 0o600 )
122+ if err != nil {
123+ panic (fmt .Errorf ("error writing passphrase file: %w" , err ))
124+ }
131125
132- certKeyEnc := pem .EncodeToMemory (encPem )
126+ certKeyEnc , err := certutil .EncryptKey (childCert .PrivateKey , pass )
127+ if err != nil {
128+ panic (err )
129+ }
133130
134- err = os .WriteFile (filepath .Join (dest , filePrefix + name + "_enc-key.pem" ), certKeyEnc , 0o600 )
135- if err != nil {
136- panic (fmt .Errorf ("could not save %s certificate encrypted key: %w" , filePrefix + name + "_enc-key.pem" , err ))
131+ err = os .WriteFile (filepath .Join (dest , filePrefix + name + "_enc-key.pem" ), certKeyEnc , 0o600 )
132+ if err != nil {
133+ panic (fmt .Errorf ("could not save %s certificate encrypted key: %w" , filePrefix + name + "_enc-key.pem" , err ))
134+ }
137135 }
138136}
139137
0 commit comments