func (c *Create) loadCertificates() ([]byte, *certificate.KeyPair, error) { defer trace.End(trace.Begin("")) c.envFile = fmt.Sprintf("%s.env", c.DisplayName) // reads each of the files specified, assuming that they are PEM encoded certs, // and constructs a byte array suitable for passing to CertPool.AppendCertsFromPEM var certs []byte for _, f := range c.clientCAs { log.Infof("Loading CA from %s", f) b, err := ioutil.ReadFile(f) if err != nil { err = errors.Errorf("Failed to load authority from file %s: %s", f, err) return nil, nil, err } certs = append(certs, b...) } var keypair *certificate.KeyPair if c.cert != "" && c.key != "" { log.Infof("Loading certificate/key pair - private key in %s", c.key) keypair = certificate.NewKeyPair(c.cert, c.key, nil, nil) if err := keypair.LoadCertificate(); err != nil { log.Errorf("Failed to load certificate: %s", err) return certs, nil, err } } return certs, keypair, nil }
func (c *Create) loadCertificate() (*certificate.Keypair, error) { defer trace.End(trace.Begin("")) var keypair *certificate.Keypair if c.cert != "" && c.key != "" { log.Infof("Loading certificate/key pair - private key in %s", c.key) keypair = certificate.NewKeyPair(false, c.key, c.cert) } else if !c.noTLS && c.DisplayName != "" { c.key = fmt.Sprintf("./%s-key.pem", c.DisplayName) c.cert = fmt.Sprintf("./%s-cert.pem", c.DisplayName) log.Infof("Generating certificate/key pair - private key in %s", c.key) keypair = certificate.NewKeyPair(true, c.key, c.cert) } if keypair == nil { log.Warnf("Configuring without TLS - to enable drop --no-tls or use --key/--cert parameters") return nil, nil } if err := keypair.GetCertificate(); err != nil { log.Errorf("Failed to read/generate certificate: %s", err) return nil, err } return keypair, nil }
func (c *Create) generateCertificates(ca bool) ([]byte, *certificate.KeyPair, error) { defer trace.End(trace.Begin("")) var certs []byte // generate the certs and keys with names conforming the default the docker client expects // to avoid overwriting for a different vch, place this in a directory named for the vch err := os.MkdirAll(fmt.Sprintf("./%s", c.DisplayName), 0700) if err != nil { log.Errorf("Unable to make directory to hold certificates") return nil, nil, err } // the locations for the certificates and env file c.envFile = fmt.Sprintf("%s/%[1]s.env", c.DisplayName) c.key = fmt.Sprintf("./%s/key.pem", c.DisplayName) c.cert = fmt.Sprintf("./%s/cert.pem", c.DisplayName) skey := fmt.Sprintf("./%s/server-key.pem", c.DisplayName) scert := fmt.Sprintf("./%s/server-cert.pem", c.DisplayName) cakey := fmt.Sprintf("./%s/ca-key.pem", c.DisplayName) c.cacert = fmt.Sprintf("./%s/ca.pem", c.DisplayName) if !ca { log.Infof("Generating self-signed certificate/key pair - private key in %s", c.key) keypair := certificate.NewKeyPair(c.key, c.cert, nil, nil) err := keypair.CreateSelfSigned(c.cname, nil, c.keySize) if err != nil { log.Errorf("Failed to generate self-signed certificate: %s", err) return nil, nil, err } return certs, keypair, nil } // if we've not got a specific CommonName but do have a static IP then go with that. if c.cname == "" && c.clientNetworkIP != "" { c.cname = c.clientNetworkIP log.Infof("Using client-network-ip as cname for server certificates - use --tls-cname to override: %s", c.cname) } if c.cname == "" { log.Error("Common Name must be provided when generating certificates for client authentication:") log.Info(" --tls-cname=<FQDN or static IP> # for the appliance VM") log.Info(" --tls-cname=<*.yourdomain.com> # if DNS has entries in that form for DHCP addresses (less secure)") log.Info(" --no-tlsverify # disables client authentication (anyone can connect to the VCH)") log.Info(" --no-tls # disables TLS entirely") log.Info("") return certs, nil, errors.New("provide Common Name for server certificate") } // for now re-use the display name as the organisation if unspecified if len(c.org) == 0 { c.org = []string{c.DisplayName} } if len(c.org) == 1 && !strings.HasPrefix(c.cname, "*") { // Add in the cname if it's not a wildcard c.org = append(c.org, c.cname) } // Certificate authority log.Infof("Generating CA certificate/key pair - private key in %s", cakey) cakp := certificate.NewKeyPair(c.cacert, cakey, nil, nil) err = cakp.CreateRootCA(c.cname, c.org, c.keySize) if err != nil { log.Errorf("Failed to generate CA: %s", err) return nil, nil, err } if err = cakp.SaveCertificate(); err != nil { log.Errorf("Failed to save CA certificates: %s", err) return nil, nil, err } // Server certificates log.Infof("Generating server certificate/key pair - private key in %s", skey) skp := certificate.NewKeyPair(scert, skey, nil, nil) err = skp.CreateServerCertificate(c.cname, c.org, c.keySize, cakp) if err != nil { log.Errorf("Failed to generate server certificates: %s", err) return nil, nil, err } if err = skp.SaveCertificate(); err != nil { log.Errorf("Failed to save server certificates: %s", err) return nil, nil, err } // Client certificates log.Infof("Generating client certificate/key pair - private key in %s", c.key) ckp := certificate.NewKeyPair(c.cert, c.key, nil, nil) err = ckp.CreateClientCertificate(c.cname, c.org, c.keySize, cakp) if err != nil { log.Errorf("Failed to generate server certificates: %s", err) return nil, nil, err } if err = ckp.SaveCertificate(); err != nil { log.Errorf("Failed to save client certificates: %s", err) return nil, nil, err } c.clientCert, err = ckp.Certificate() if err != nil { log.Warnf("Failed to stash client certificate for later application level validation: %s", err) } // If openssl is present, try to generate a browser friendly pfx file (a bundle of the public certificate AND the private key) // The pfx file can be imported directly into keychains for client certificate authentication args := strings.Split(fmt.Sprintf("pkcs12 -export -out ./%[1]s/cert.pfx -inkey ./%[1]s/key.pem -in ./%[1]s/cert.pem -certfile ./%[1]s/ca.pem -password pass:"******" ") pfx := exec.Command("openssl", args...) out, err := pfx.CombinedOutput() if err != nil { log.Debug(out) log.Warnf("Failed to generate browser friendly PFX client certificate: %s", err) } else { log.Infof("Generated browser friendly PFX client certificate - certificate in ./%s/cert.pfx", c.DisplayName) } return cakp.CertPEM, skp, nil }