@@ -21,9 +21,16 @@ import (
2121
2222var defaultGenerator = NewX509CertGenerator ()
2323
24+ type Options struct {
25+ Hosts []string
26+ CertFile , KeyFile , CAFile , CAKeyFile , Org string
27+ Bits int
28+ SwarmMaster bool
29+ }
30+
2431type Generator interface {
2532 GenerateCACertificate (certFile , keyFile , org string , bits int ) error
26- GenerateCert (hosts [] string , certFile , keyFile , caFile , caKeyFile , org string , bits int ) error
33+ GenerateCert (opts * Options ) error
2734 ReadTLSConfig (addr string , authOptions * auth.Options ) (* tls.Config , error )
2835 ValidateCertificate (addr string , authOptions * auth.Options ) (bool , error )
2936}
@@ -38,8 +45,8 @@ func GenerateCACertificate(certFile, keyFile, org string, bits int) error {
3845 return defaultGenerator .GenerateCACertificate (certFile , keyFile , org , bits )
3946}
4047
41- func GenerateCert (hosts [] string , certFile , keyFile , caFile , caKeyFile , org string , bits int ) error {
42- return defaultGenerator .GenerateCert (hosts , certFile , keyFile , caFile , caKeyFile , org , bits )
48+ func GenerateCert (opts * Options ) error {
49+ return defaultGenerator .GenerateCert (opts )
4350}
4451
4552func ValidateCertificate (addr string , authOptions * auth.Options ) (bool , error ) {
@@ -150,18 +157,24 @@ func (xcg *X509CertGenerator) GenerateCACertificate(certFile, keyFile, org strin
150157// certificate authority files and stores the result in the certificate
151158// file and key provided. The provided host names are set to the
152159// appropriate certificate fields.
153- func (xcg * X509CertGenerator ) GenerateCert (hosts [] string , certFile , keyFile , caFile , caKeyFile , org string , bits int ) error {
154- template , err := xcg .newCertificate (org )
160+ func (xcg * X509CertGenerator ) GenerateCert (opts * Options ) error {
161+ template , err := xcg .newCertificate (opts . Org )
155162 if err != nil {
156163 return err
157164 }
158165 // client
159- if len (hosts ) == 1 && hosts [0 ] == "" {
166+ if len (opts . Hosts ) == 1 && opts . Hosts [0 ] == "" {
160167 template .ExtKeyUsage = []x509.ExtKeyUsage {x509 .ExtKeyUsageClientAuth }
161168 template .KeyUsage = x509 .KeyUsageDigitalSignature
162169 } else { // server
163- template .ExtKeyUsage = []x509.ExtKeyUsage {x509 .ExtKeyUsageClientAuth , x509 .ExtKeyUsageServerAuth }
164- for _ , h := range hosts {
170+ template .ExtKeyUsage = []x509.ExtKeyUsage {x509 .ExtKeyUsageServerAuth }
171+ if opts .SwarmMaster {
172+ // Extend the Swarm master's server certificate
173+ // permissions to also be able to connect to downstream
174+ // nodes as a client.
175+ template .ExtKeyUsage = append (template .ExtKeyUsage , x509 .ExtKeyUsageClientAuth )
176+ }
177+ for _ , h := range opts .Hosts {
165178 if ip := net .ParseIP (h ); ip != nil {
166179 template .IPAddresses = append (template .IPAddresses , ip )
167180 } else {
@@ -170,12 +183,12 @@ func (xcg *X509CertGenerator) GenerateCert(hosts []string, certFile, keyFile, ca
170183 }
171184 }
172185
173- tlsCert , err := tls .LoadX509KeyPair (caFile , caKeyFile )
186+ tlsCert , err := tls .LoadX509KeyPair (opts . CAFile , opts . CAKeyFile )
174187 if err != nil {
175188 return err
176189 }
177190
178- priv , err := rsa .GenerateKey (rand .Reader , bits )
191+ priv , err := rsa .GenerateKey (rand .Reader , opts . Bits )
179192 if err != nil {
180193 return err
181194 }
@@ -190,15 +203,15 @@ func (xcg *X509CertGenerator) GenerateCert(hosts []string, certFile, keyFile, ca
190203 return err
191204 }
192205
193- certOut , err := os .Create (certFile )
206+ certOut , err := os .Create (opts . CertFile )
194207 if err != nil {
195208 return err
196209 }
197210
198211 pem .Encode (certOut , & pem.Block {Type : "CERTIFICATE" , Bytes : derBytes })
199212 certOut .Close ()
200213
201- keyOut , err := os .OpenFile (keyFile , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0600 )
214+ keyOut , err := os .OpenFile (opts . KeyFile , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0600 )
202215 if err != nil {
203216 return err
204217 }
@@ -212,28 +225,28 @@ func (xcg *X509CertGenerator) GenerateCert(hosts []string, certFile, keyFile, ca
212225// ReadTLSConfig reads the tls config for a machine.
213226func (xcg * X509CertGenerator ) ReadTLSConfig (addr string , authOptions * auth.Options ) (* tls.Config , error ) {
214227 caCertPath := authOptions .CaCertPath
215- serverCertPath := authOptions .ServerCertPath
216- serverKeyPath := authOptions .ServerKeyPath
228+ clientCertPath := authOptions .ClientCertPath
229+ clientKeyPath := authOptions .ClientKeyPath
217230
218231 log .Debugf ("Reading CA certificate from %s" , caCertPath )
219232 caCert , err := ioutil .ReadFile (caCertPath )
220233 if err != nil {
221234 return nil , err
222235 }
223236
224- log .Debugf ("Reading server certificate from %s" , serverCertPath )
225- serverCert , err := ioutil .ReadFile (serverCertPath )
237+ log .Debugf ("Reading client certificate from %s" , clientCertPath )
238+ clientCert , err := ioutil .ReadFile (clientCertPath )
226239 if err != nil {
227240 return nil , err
228241 }
229242
230- log .Debugf ("Reading server key from %s" , serverKeyPath )
231- serverKey , err := ioutil .ReadFile (serverKeyPath )
243+ log .Debugf ("Reading client key from %s" , clientKeyPath )
244+ clientKey , err := ioutil .ReadFile (clientKeyPath )
232245 if err != nil {
233246 return nil , err
234247 }
235248
236- return xcg .getTLSConfig (caCert , serverCert , serverKey , false )
249+ return xcg .getTLSConfig (caCert , clientCert , clientKey , false )
237250}
238251
239252// ValidateCertificate validate the certificate installed on the vm.
0 commit comments