Example #1
0
func (certSuite) TestVerify(c *gc.C) {
	now := time.Now()
	caCert, caKey, err := cert.NewCA("foo", now.Add(1*time.Minute))
	c.Assert(err, jc.ErrorIsNil)

	var noHostnames []string
	srvCert, _, err := cert.NewServer(caCert, caKey, now.Add(3*time.Minute), noHostnames)
	c.Assert(err, jc.ErrorIsNil)

	err = cert.Verify(srvCert, caCert, now)
	c.Assert(err, jc.ErrorIsNil)

	err = cert.Verify(srvCert, caCert, now.Add(55*time.Second))
	c.Assert(err, jc.ErrorIsNil)

	err = cert.Verify(srvCert, caCert, now.AddDate(0, 0, -8))
	c.Check(err, gc.ErrorMatches, "x509: certificate has expired or is not yet valid")

	err = cert.Verify(srvCert, caCert, now.Add(2*time.Minute))
	c.Check(err, gc.ErrorMatches, "x509: certificate has expired or is not yet valid")

	caCert2, caKey2, err := cert.NewCA("bar", now.Add(1*time.Minute))
	c.Assert(err, jc.ErrorIsNil)

	// Check original server certificate against wrong CA.
	err = cert.Verify(srvCert, caCert2, now)
	c.Check(err, gc.ErrorMatches, "x509: certificate signed by unknown authority")

	srvCert2, _, err := cert.NewServer(caCert2, caKey2, now.Add(1*time.Minute), noHostnames)
	c.Assert(err, jc.ErrorIsNil)

	// Check new server certificate against original CA.
	err = cert.Verify(srvCert2, caCert, now)
	c.Check(err, gc.ErrorMatches, "x509: certificate signed by unknown authority")
}
Example #2
0
func (certSuite) TestNewServer(c *gc.C) {
	now := time.Now()
	expiry := roundTime(now.AddDate(1, 0, 0))
	caCertPEM, caKeyPEM, err := cert.NewCA("foo", expiry)
	c.Assert(err, gc.IsNil)

	caCert, _, err := cert.ParseCertAndKey(caCertPEM, caKeyPEM)
	c.Assert(err, gc.IsNil)

	var noHostnames []string
	srvCertPEM, srvKeyPEM, err := cert.NewServer(caCertPEM, caKeyPEM, expiry, noHostnames)
	c.Assert(err, gc.IsNil)

	srvCert, srvKey, err := cert.ParseCertAndKey(srvCertPEM, srvKeyPEM)
	c.Assert(err, gc.IsNil)
	c.Assert(srvCert.Subject.CommonName, gc.Equals, "*")
	// Check that the certificate is valid from one week before today.
	c.Check(srvCert.NotBefore.Before(now), jc.IsTrue)
	c.Check(srvCert.NotBefore.Before(now.AddDate(0, 0, -6)), jc.IsTrue)
	c.Check(srvCert.NotBefore.After(now.AddDate(0, 0, -8)), jc.IsTrue)
	c.Assert(srvCert.NotAfter.Equal(expiry), gc.Equals, true)
	c.Assert(srvCert.BasicConstraintsValid, gc.Equals, false)
	c.Assert(srvCert.IsCA, gc.Equals, false)
	c.Assert(srvCert.ExtKeyUsage, gc.DeepEquals, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth})

	checkTLSConnection(c, caCert, srvCert, srvKey)
}
Example #3
0
func (s *certPoolSuite) addCert(c *gc.C, filename string) {
	expiry := time.Now().UTC().AddDate(10, 0, 0)
	pem, _, err := cert.NewCA("random env name", "1", expiry)
	c.Assert(err, jc.ErrorIsNil)
	err = ioutil.WriteFile(filename, []byte(pem), 0644)
	c.Assert(err, jc.ErrorIsNil)
}
Example #4
0
File: cert.go Project: imoapps/juju
func mustNewCA() (string, string) {
	cert.KeyBits = 512
	caCert, caKey, err := cert.NewCA("juju testing", time.Now().AddDate(10, 0, 0))
	if err != nil {
		panic(err)
	}
	return string(caCert), string(caKey)
}
Example #5
0
func createCerts(c *gc.C, serverName string) (*x509.CertPool, tls.Certificate) {
	certCaPem, keyCaPem, err := cert.NewCA("sender-test", "1", time.Now().Add(time.Minute))
	c.Assert(err, jc.ErrorIsNil)
	certPem, keyPem, err := cert.NewServer(certCaPem, keyCaPem, time.Now().Add(time.Minute), []string{serverName})
	c.Assert(err, jc.ErrorIsNil)
	cert, err := tls.X509KeyPair([]byte(certPem), []byte(keyPem))
	c.Assert(err, jc.ErrorIsNil)
	certPool := x509.NewCertPool()
	certPool.AppendCertsFromPEM([]byte(certCaPem))
	return certPool, cert
}
Example #6
0
func (certSuite) TestNewServer(c *gc.C) {
	now := time.Now()
	expiry := roundTime(now.AddDate(1, 0, 0))
	caCertPEM, caKeyPEM, err := cert.NewCA("foo", expiry)
	c.Assert(err, jc.ErrorIsNil)

	caCert, _, err := cert.ParseCertAndKey(caCertPEM, caKeyPEM)
	c.Assert(err, jc.ErrorIsNil)

	srvCertPEM, srvKeyPEM, err := cert.NewServer(caCertPEM, caKeyPEM, expiry, nil)
	c.Assert(err, jc.ErrorIsNil)
	checkCertificate(c, caCert, srvCertPEM, srvKeyPEM, now, expiry)
}
Example #7
0
func (certSuite) TestWithNonUTCExpiry(c *gc.C) {
	expiry, err := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", "2012-11-28 15:53:57 +0100 CET")
	c.Assert(err, jc.ErrorIsNil)
	certPEM, keyPEM, err := cert.NewCA("foo", expiry)
	xcert, err := cert.ParseCert(certPEM)
	c.Assert(err, jc.ErrorIsNil)
	checkNotAfter(c, xcert, expiry)

	var noHostnames []string
	certPEM, _, err = cert.NewServer(certPEM, keyPEM, expiry, noHostnames)
	xcert, err = cert.ParseCert(certPEM)
	c.Assert(err, jc.ErrorIsNil)
	checkNotAfter(c, xcert, expiry)
}
Example #8
0
// ensureCertificates ensures that a CA certificate,
// server certificate, and private key exist in the log
// directory, and writes them if not. The CA certificate
// is entered into the environment configuration to be
// picked up by other agents.
func (h *RsyslogConfigHandler) ensureCertificates() error {
	// We write ca-cert.pem last, after propagating into state.
	// If it's there, then there's nothing to do. Otherwise,
	// start over.
	caCertPEM := h.syslogConfig.CACertPath()
	if _, err := os.Stat(caCertPEM); err == nil {
		return nil
	}

	// Files must be chowned to syslog:adm.
	syslogUid, syslogGid, err := lookupUser("syslog")
	if err != nil {
		return err
	}

	// Generate a new CA and server cert/key pairs.
	// The CA key will be discarded after the server
	// cert has been generated.
	expiry := time.Now().UTC().AddDate(10, 0, 0)
	caCertPEM, caKeyPEM, err := cert.NewCA("rsyslog", expiry)
	if err != nil {
		return err
	}
	rsyslogCertPEM, rsyslogKeyPEM, err := cert.NewServer(caCertPEM, caKeyPEM, expiry, nil)
	if err != nil {
		return err
	}

	// Update the environment config with the CA cert,
	// so clients can configure rsyslog.
	if err := h.st.SetRsyslogCert(caCertPEM); err != nil {
		return err
	}

	// Write the certificates and key. The CA certificate must be written last for idempotency.
	for _, pair := range []struct {
		path string
		data string
	}{
		{h.syslogConfig.ServerCertPath(), rsyslogCertPEM},
		{h.syslogConfig.ServerKeyPath(), rsyslogKeyPEM},
		{h.syslogConfig.CACertPath(), caCertPEM},
	} {
		if err := writeFileAtomic(pair.path, []byte(pair.data), 0600, syslogUid, syslogGid); err != nil {
			return err
		}
	}
	return nil
}
Example #9
0
func (certSuite) TestNewCA(c *gc.C) {
	expiry := roundTime(time.Now().AddDate(0, 0, 1))
	caCertPEM, caKeyPEM, err := cert.NewCA("foo", expiry)
	c.Assert(err, gc.IsNil)

	caCert, caKey, err := cert.ParseCertAndKey(caCertPEM, caKeyPEM)
	c.Assert(err, gc.IsNil)

	c.Assert(caKey, gc.FitsTypeOf, (*rsa.PrivateKey)(nil))
	c.Assert(caCert.Subject.CommonName, gc.Equals, `juju-generated CA for environment "foo"`)
	c.Assert(caCert.NotAfter.Equal(expiry), gc.Equals, true)
	c.Assert(caCert.BasicConstraintsValid, gc.Equals, true)
	c.Assert(caCert.IsCA, gc.Equals, true)
	//c.Assert(caCert.MaxPathLen, Equals, 0)	TODO it ends up as -1 - check that this is ok.
}
Example #10
0
func (certSuite) TestNewCA(c *gc.C) {
	now := time.Now()
	expiry := roundTime(now.AddDate(0, 0, 1))
	caCertPEM, caKeyPEM, err := cert.NewCA("foo", expiry)
	c.Assert(err, jc.ErrorIsNil)

	caCert, caKey, err := cert.ParseCertAndKey(caCertPEM, caKeyPEM)
	c.Assert(err, jc.ErrorIsNil)

	c.Check(caKey, gc.FitsTypeOf, (*rsa.PrivateKey)(nil))
	c.Check(caCert.Subject.CommonName, gc.Equals, `juju-generated CA for model "foo"`)
	checkNotBefore(c, caCert, now)
	checkNotAfter(c, caCert, expiry)
	c.Check(caCert.BasicConstraintsValid, jc.IsTrue)
	c.Check(caCert.IsCA, jc.IsTrue)
	//c.Assert(caCert.MaxPathLen, Equals, 0)	TODO it ends up as -1 - check that this is ok.
}
Example #11
0
File: open.go Project: zhouqt/juju
// ensureCertificate generates a new CA certificate and
// attaches it to the given environment configuration,
// unless the configuration already has one.
func ensureCertificate(cfg *config.Config) (*config.Config, error) {
	_, hasCACert := cfg.CACert()
	_, hasCAKey := cfg.CAPrivateKey()
	if hasCACert && hasCAKey {
		return cfg, nil
	}
	if hasCACert && !hasCAKey {
		return nil, fmt.Errorf("environment configuration with a certificate but no CA private key")
	}

	caCert, caKey, err := cert.NewCA(cfg.Name(), time.Now().UTC().AddDate(10, 0, 0))
	if err != nil {
		return nil, err
	}
	return cfg.Apply(map[string]interface{}{
		"ca-cert":        string(caCert),
		"ca-private-key": string(caKey),
	})
}
Example #12
0
func (certSuite) TestNewCA(c *gc.C) {
	now := time.Now()
	expiry := roundTime(now.AddDate(0, 0, 1))
	caCertPEM, caKeyPEM, err := cert.NewCA("foo", expiry)
	c.Assert(err, gc.IsNil)

	caCert, caKey, err := cert.ParseCertAndKey(caCertPEM, caKeyPEM)
	c.Assert(err, gc.IsNil)

	c.Check(caKey, gc.FitsTypeOf, (*rsa.PrivateKey)(nil))
	c.Check(caCert.Subject.CommonName, gc.Equals, `juju-generated CA for environment "foo"`)
	// Check that the certificate is valid from one week before today.
	c.Check(caCert.NotBefore.Before(now), jc.IsTrue)
	c.Check(caCert.NotBefore.Before(now.AddDate(0, 0, -6)), jc.IsTrue)
	c.Check(caCert.NotBefore.After(now.AddDate(0, 0, -8)), jc.IsTrue)
	c.Check(caCert.NotAfter.Equal(expiry), gc.Equals, true)
	c.Check(caCert.BasicConstraintsValid, gc.Equals, true)
	c.Check(caCert.IsCA, gc.Equals, true)
	//c.Assert(caCert.MaxPathLen, Equals, 0)	TODO it ends up as -1 - check that this is ok.
}
Example #13
0
// ensureCertificates ensures that a CA certificate,
// server certificate, and private key exist in the log
// directory, and writes them if not. The CA certificate
// is entered into the environment configuration to be
// picked up by other agents.
func (h *RsyslogConfigHandler) ensureCertificates() error {
	// We write ca-cert.pem last, after propagating into state.
	// If it's there, then there's nothing to do. Otherwise,
	// start over.
	caCertPEM := h.syslogConfig.CACertPath()
	if _, err := os.Stat(caCertPEM); err == nil {
		return nil
	}

	// Generate a new CA and server cert/key pairs.
	// The CA key will be discarded after the server
	// cert has been generated.
	expiry := time.Now().UTC().AddDate(10, 0, 0)
	caCertPEM, caKeyPEM, err := cert.NewCA("rsyslog", expiry)
	if err != nil {
		return err
	}

	// Update the environment config with the CA cert,
	// so clients can configure rsyslog.
	if err := h.st.SetRsyslogCert(caCertPEM, caKeyPEM); err != nil {
		return err
	}

	rsyslogCertPEM, rsyslogKeyPEM, err := h.rsyslogServerCerts(caCertPEM, caKeyPEM)
	if err != nil {
		return err
	}

	if err := writeCertificates([]certPair{
		{h.syslogConfig.ServerCertPath(), rsyslogCertPEM},
		{h.syslogConfig.ServerKeyPath(), rsyslogKeyPEM},
		{h.syslogConfig.CACertPath(), caCertPEM},
	}); err != nil {
		return errors.Trace(err)
	}

	return nil
}
Example #14
0
func (certSuite) TestNewServer(c *gc.C) {
	expiry := roundTime(time.Now().AddDate(1, 0, 0))
	caCertPEM, caKeyPEM, err := cert.NewCA("foo", expiry)
	c.Assert(err, gc.IsNil)

	caCert, _, err := cert.ParseCertAndKey(caCertPEM, caKeyPEM)
	c.Assert(err, gc.IsNil)

	var noHostnames []string
	srvCertPEM, srvKeyPEM, err := cert.NewServer(caCertPEM, caKeyPEM, expiry, noHostnames)
	c.Assert(err, gc.IsNil)

	srvCert, srvKey, err := cert.ParseCertAndKey(srvCertPEM, srvKeyPEM)
	c.Assert(err, gc.IsNil)
	c.Assert(srvCert.Subject.CommonName, gc.Equals, "*")
	c.Assert(srvCert.NotAfter.Equal(expiry), gc.Equals, true)
	c.Assert(srvCert.BasicConstraintsValid, gc.Equals, false)
	c.Assert(srvCert.IsCA, gc.Equals, false)
	c.Assert(srvCert.ExtKeyUsage, gc.DeepEquals, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth})

	checkTLSConnection(c, caCert, srvCert, srvKey)
}
Example #15
0
// ensureCA ensures that a CA certificate and key exist in state,
// to be picked up by all rsyslog workers in the environment.
func (h *RsyslogConfigHandler) ensureCA() error {
	// We never write the CA key to local disk, so
	// we must check state to know whether or not
	// we need to generate new certs and keys.
	cfg, err := h.st.GetRsyslogConfig(h.tag.String())
	if err != nil {
		return errors.Annotate(err, "cannot get environ config")
	}
	if cfg.CACert != "" && cfg.CAKey != "" {
		return nil
	}

	// Generate a new CA and server cert/key pairs, and
	// publish to state. Rsyslog workers will observe
	// this and generate certificates and keys for
	// rsyslog in response.
	expiry := time.Now().UTC().AddDate(10, 0, 0)
	caCertPEM, caKeyPEM, err := cert.NewCA("rsyslog", expiry)
	if err != nil {
		return err
	}
	return h.st.SetRsyslogCert(caCertPEM, caKeyPEM)
}
Example #16
0
// ensureCertificate generates a new CA certificate and
// attaches it to the given controller configuration,
// unless the configuration already has one.
func ensureCertificate(cfg *config.Config) (*config.Config, string, error) {
	caCert, hasCACert := cfg.CACert()
	_, hasCAKey := cfg.CAPrivateKey()
	if hasCACert && hasCAKey {
		return cfg, caCert, nil
	}
	if hasCACert && !hasCAKey {
		return nil, "", errors.Errorf("controller configuration with a certificate but no CA private key")
	}

	caCert, caKey, err := cert.NewCA(cfg.Name(), cfg.UUID(), time.Now().UTC().AddDate(10, 0, 0))
	if err != nil {
		return nil, "", errors.Trace(err)
	}
	cfg, err = cfg.Apply(map[string]interface{}{
		config.CACertKey: string(caCert),
		"ca-private-key": string(caKey),
	})
	if err != nil {
		return nil, "", errors.Trace(err)
	}
	return cfg, string(caCert), nil
}
Example #17
0
File: config.go Project: bac/juju
// NewConfig creates a new Config from the supplied attributes.
// Default values will be used where defaults are available.
//
// If ca-cert or ca-private-key are not set, then we will check
// if ca-cert-path or ca-private-key-path are set, and read the
// contents. If none of those are set, we will look for files
// in well-defined locations: $JUJU_DATA/ca-cert.pem, and
// $JUJU_DATA/ca-private-key.pem. If none of these are set, an
// error is returned.
func NewConfig(attrs map[string]interface{}) (Config, error) {
	coerced, err := configChecker.Coerce(attrs, nil)
	if err != nil {
		return Config{}, errors.Trace(err)
	}
	attrs = coerced.(map[string]interface{})
	config := Config{
		BootstrapTimeout:        time.Duration(attrs[BootstrapTimeoutKey].(int)) * time.Second,
		BootstrapRetryDelay:     time.Duration(attrs[BootstrapRetryDelayKey].(int)) * time.Second,
		BootstrapAddressesDelay: time.Duration(attrs[BootstrapAddressesDelayKey].(int)) * time.Second,
	}

	if adminSecret, ok := attrs[AdminSecretKey].(string); ok {
		config.AdminSecret = adminSecret
	} else {
		// Generate a random admin secret.
		buf := make([]byte, 16)
		if _, err := io.ReadFull(rand.Reader, buf); err != nil {
			return Config{}, errors.Annotate(err, "generating random "+AdminSecretKey)
		}
		config.AdminSecret = fmt.Sprintf("%x", buf)
	}

	if caCert, ok := attrs[CACertKey].(string); ok {
		config.CACert = caCert
	} else {
		var userSpecified bool
		var err error
		config.CACert, userSpecified, err = readFileAttr(attrs, CACertKey, CACertKey+".pem")
		if err != nil && (userSpecified || !os.IsNotExist(errors.Cause(err))) {
			return Config{}, errors.Annotatef(err, "reading %q from file", CACertKey)
		}
	}

	if caPrivateKey, ok := attrs[CAPrivateKeyKey].(string); ok {
		config.CAPrivateKey = caPrivateKey
	} else {
		var userSpecified bool
		var err error
		config.CAPrivateKey, userSpecified, err = readFileAttr(attrs, CAPrivateKeyKey, CAPrivateKeyKey+".pem")
		if err != nil && (userSpecified || !os.IsNotExist(errors.Cause(err))) {
			return Config{}, errors.Annotatef(err, "reading %q from file", CAPrivateKeyKey)
		}
	}

	if config.CACert == "" && config.CAPrivateKey == "" {
		// Generate a new CA certificate and private key.
		// TODO(perrito666) 2016-05-02 lp:1558657
		expiry := time.Now().UTC().AddDate(10, 0, 0)
		uuid, err := utils.NewUUID()
		if err != nil {
			return Config{}, errors.Annotate(err, "generating UUID for CA certificate")
		}
		caCert, caKey, err := cert.NewCA("juju-ca", uuid.String(), expiry)
		if err != nil {
			return Config{}, errors.Trace(err)
		}
		config.CACert = caCert
		config.CAPrivateKey = caKey
	}

	return config, config.Validate()
}
Example #18
0
// ensureCertificates ensures that a CA certificate,
// server certificate, and private key exist in the log
// directory, and writes them if not. The CA certificate
// is entered into the environment configuration to be
// picked up by other agents.
func (h *RsyslogConfigHandler) ensureCertificates() error {
	// We write ca-cert.pem last, after propagating into state.
	// If it's there, then there's nothing to do. Otherwise,
	// start over.
	caCertPEM := h.syslogConfig.CACertPath()
	if _, err := os.Stat(caCertPEM); err == nil {
		return nil
	}

	// Files must be chowned to syslog:adm.
	syslogUid, syslogGid, err := lookupUser("syslog")
	if err != nil {
		return err
	}

	// Generate a new CA and server cert/key pairs.
	// The CA key will be discarded after the server
	// cert has been generated.
	expiry := time.Now().UTC().AddDate(10, 0, 0)
	caCertPEM, caKeyPEM, err := cert.NewCA("rsyslog", expiry)
	if err != nil {
		return err
	}

	// Add rsyslog servers in the subjectAltName so we can
	// successfully validate when connectiong via SSL
	hosts, err := h.rsyslogHosts()
	if err != nil {
		return err
	}
	// Add local IPs to SAN. When connecting via IP address,
	// the client will validate the server against any IP in
	// the subjectAltName. We add all local ips to make sure
	// this does not cause an error
	ips, err := localIPS()
	if err != nil {
		return err
	}
	hosts = append(hosts, ips...)
	rsyslogCertPEM, rsyslogKeyPEM, err := cert.NewServer(caCertPEM, caKeyPEM, expiry, hosts)
	if err != nil {
		return err
	}

	// Update the environment config with the CA cert,
	// so clients can configure rsyslog.
	if err := h.st.SetRsyslogCert(caCertPEM); err != nil {
		return err
	}

	// Write the certificates and key. The CA certificate must be written last for idempotency.
	for _, pair := range []struct {
		path string
		data string
	}{
		{h.syslogConfig.ServerCertPath(), rsyslogCertPEM},
		{h.syslogConfig.ServerKeyPath(), rsyslogKeyPEM},
		{h.syslogConfig.CACertPath(), caCertPEM},
	} {
		if err := writeFileAtomic(pair.path, []byte(pair.data), 0600, syslogUid, syslogGid); err != nil {
			return err
		}
	}
	return nil
}