Exemplo n.º 1
0
Arquivo: create.go Projeto: vmware/vic
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
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
Arquivo: create.go Projeto: vmware/vic
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
}