Ejemplo n.º 1
0
// NewSigner generates a new certificate signer from a Root structure.
// This is one of two standard signers: local or remote. If the root
// structure specifies a force remote, then a remote signer is created,
// otherwise either a remote or local signer is generated based on the
// policy. For a local signer, the CertFile and KeyFile need to be
// defined in Root.
func NewSigner(root Root, policy *config.Signing) (signer.Signer, error) {
	if policy == nil {
		policy = &config.Signing{
			Profiles: map[string]*config.SigningProfile{},
			Default:  config.DefaultConfig(),
		}
	}

	if !policy.Valid() {
		return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
	}

	var s signer.Signer
	var err error
	if root.ForceRemote {
		s, err = remote.NewSigner(policy)
	} else {
		if policy.NeedsLocalSigner() && policy.NeedsRemoteSigner() {
			s, err = newUniversalSigner(root, policy)
		} else {
			if policy.NeedsLocalSigner() {
				s, err = newLocalSigner(root, policy)
			}
			if policy.NeedsRemoteSigner() {
				s, err = remote.NewSigner(policy)
			}
		}
	}

	return s, err
}
Ejemplo n.º 2
0
// NewCertGeneratorHandler builds a new handler for generating
// certificates directly from certificate requests; the validator covers
// the certificate request and the CA's key and certificate are used to
// sign the generated request. If remote is not an empty string, the
// handler will send signature requests to the CFSSL instance contained
// in remote.
func NewCertGeneratorHandler(validator Validator, caFile, caKeyFile string, policy *config.Signing) (http.Handler, error) {
	var err error
	log.Info("setting up new generator / signer")
	cg := new(CertGeneratorHandler)

	if policy == nil {
		policy = &config.Signing{
			Default:  config.DefaultConfig(),
			Profiles: nil,
		}
	}

	root := universal.Root{
		Config: map[string]string{
			"ca-file":     caFile,
			"ca-key-file": caKeyFile,
		},
	}
	if cg.signer, err = universal.NewSigner(root, policy); err != nil {
		log.Errorf("setting up signer failed: %v", err)
		return nil, err
	}

	cg.generator = &csr.Generator{Validator: validator}

	return api.HTTPHandler{Handler: cg, Methods: []string{"POST"}}, nil
}
Ejemplo n.º 3
0
// SignerFromConfigAndDB takes the Config and creates the appropriate
// signer.Signer object with a specified db
func SignerFromConfigAndDB(c cli.Config, db *sql.DB) (signer.Signer, error) {
	// If there is a config, use its signing policy. Otherwise create a default policy.
	var policy *config.Signing
	if c.CFG != nil {
		policy = c.CFG.Signing
	} else {
		policy = &config.Signing{
			Profiles: map[string]*config.SigningProfile{},
			Default:  config.DefaultConfig(),
		}
	}

	// Make sure the policy reflects the new remote
	if c.Remote != "" {
		err := policy.OverrideRemotes(c.Remote)
		if err != nil {
			log.Infof("Invalid remote %v, reverting to configuration default", c.Remote)
			return nil, err
		}
	}

	s, err := universal.NewSigner(cli.RootFromConfig(&c), policy)
	if err != nil {
		return nil, err
	}

	s.SetDB(db)

	return s, nil
}
Ejemplo n.º 4
0
func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Duration, caCertFile, caKeyFile string, approveAllKubeletCSRsForGroup string) (*CertificateController, error) {
	// Send events to the apiserver
	eventBroadcaster := record.NewBroadcaster()
	eventBroadcaster.StartLogging(glog.Infof)
	eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: kubeClient.Core().Events("")})

	// Configure cfssl signer
	// TODO: support non-default policy and remote/pkcs11 signing
	policy := &config.Signing{
		Default: config.DefaultConfig(),
	}
	ca, err := local.NewSignerFromFile(caCertFile, caKeyFile, policy)
	if err != nil {
		return nil, err
	}

	cc := &CertificateController{
		kubeClient: kubeClient,
		queue:      workqueue.New(),
		signer:     ca,
		approveAllKubeletCSRsForGroup: approveAllKubeletCSRsForGroup,
	}

	// Manage the addition/update of certificate requests
	cc.csrStore.Store, cc.csrController = framework.NewInformer(
		&cache.ListWatch{
			ListFunc: func(options api.ListOptions) (runtime.Object, error) {
				return cc.kubeClient.Certificates().CertificateSigningRequests().List(options)
			},
			WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
				return cc.kubeClient.Certificates().CertificateSigningRequests().Watch(options)
			},
		},
		&certificates.CertificateSigningRequest{},
		syncPeriod,
		framework.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				csr := obj.(*certificates.CertificateSigningRequest)
				glog.V(4).Infof("Adding certificate request %s", csr.Name)
				cc.enqueueCertificateRequest(obj)
			},
			UpdateFunc: func(old, new interface{}) {
				oldCSR := old.(*certificates.CertificateSigningRequest)
				glog.V(4).Infof("Updating certificate request %s", oldCSR.Name)
				cc.enqueueCertificateRequest(new)
			},
			DeleteFunc: func(obj interface{}) {
				csr := obj.(*certificates.CertificateSigningRequest)
				glog.V(4).Infof("Deleting certificate request %s", csr.Name)
				cc.enqueueCertificateRequest(obj)
			},
		},
	)
	cc.syncHandler = cc.maybeSignCertificate
	return cc, nil
}
Ejemplo n.º 5
0
// NewSigner generates a new certificate signer from a Root structure.
// This is one of two standard signers: local or remote. If the root
// structure specifies a force remote, then a remote signer is created,
// otherwise either a remote or local signer is generated based on the
// policy. For a local signer, the CertFile and KeyFile need to be
// defined in Root.
func NewSigner(root Root, policy *config.Signing) (signer.Signer, error) {
	if policy == nil {
		policy = &config.Signing{
			Profiles: map[string]*config.SigningProfile{},
			Default:  config.DefaultConfig(),
		}
	}

	if !policy.Valid() {
		return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
	}

	var s signer.Signer
	var err error
	if root.ForceRemote {
		s, err = remote.NewSigner(policy)
	} else {
		if policy.NeedsLocalSigner() && policy.NeedsRemoteSigner() {
			// Currently we don't support a hybrid signer
			return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
		}

		if policy.NeedsLocalSigner() {
			// shouldProvide indicates whether the
			// function *should* have produced a key. If
			// it's true, we should use the signer and
			// error returned. Otherwise, keep looking for
			// signers.
			var shouldProvide bool
			// localSignerList is defined in the
			// universal_signers*.go files. These activate
			// and deactivate signers based on build
			// flags; for example,
			// universal_signers_pkcs11.go contains a list
			// of valid signers when PKCS #11 is turned
			// on.
			for _, possibleSigner := range localSignerList {
				s, shouldProvide, err = possibleSigner(&root, policy)
				if shouldProvide {
					break
				}
			}

			if s == nil {
				err = cferr.New(cferr.PrivateKeyError, cferr.Unknown)
			}
		}

		if policy.NeedsRemoteSigner() {
			s, err = remote.NewSigner(policy)
		}
	}

	return s, err
}
Ejemplo n.º 6
0
// SignerFromConfigAndDB takes the Config and creates the appropriate
// signer.Signer object with a specified db
func SignerFromConfigAndDB(c cli.Config, db *sqlx.DB) (signer.Signer, error) {
	// If there is a config, use its signing policy. Otherwise create a default policy.
	var policy *config.Signing
	if c.CFG != nil {
		policy = c.CFG.Signing
	} else {
		policy = &config.Signing{
			Profiles: map[string]*config.SigningProfile{},
			Default:  config.DefaultConfig(),
		}
	}

	// Make sure the policy reflects the new remote
	if c.Remote != "" {
		err := policy.OverrideRemotes(c.Remote)
		if err != nil {
			log.Infof("Invalid remote %v, reverting to configuration default", c.Remote)
			return nil, err
		}
	}

	if c.MutualTLSCertFile != "" && c.MutualTLSKeyFile != "" {
		err := policy.SetClientCertKeyPairFromFile(c.MutualTLSCertFile, c.MutualTLSKeyFile)
		if err != nil {
			log.Infof("Invalid mutual-tls-cert: %s or mutual-tls-key: %s, defaulting to no client auth", c.MutualTLSCertFile, c.MutualTLSKeyFile)
			return nil, err
		}
		log.Infof("Using client auth with mutual-tls-cert: %s and mutual-tls-key: %s", c.MutualTLSCertFile, c.MutualTLSKeyFile)
	}

	if c.TLSRemoteCAs != "" {
		err := policy.SetRemoteCAsFromFile(c.TLSRemoteCAs)
		if err != nil {
			log.Infof("Invalid tls-remote-ca: %s, defaulting to system trust store", c.TLSRemoteCAs)
			return nil, err
		}
		log.Infof("Using trusted CA from tls-remote-ca: %s", c.TLSRemoteCAs)
	}

	s, err := universal.NewSigner(cli.RootFromConfig(&c), policy)
	if err != nil {
		return nil, err
	}

	if db != nil {
		dbAccessor := certsql.NewAccessor(db)
		s.SetDBAccessor(dbAccessor)
	}

	return s, nil
}
func testGenerateKeypair(req *csr.CertificateRequest) (keyFile, certFile string, err error) {
	fail := func(err error) (string, string, error) {
		if keyFile != "" {
			os.Remove(keyFile)
		}
		if certFile != "" {
			os.Remove(certFile)
		}
		return "", "", err
	}

	keyFile, err = tempName()
	if err != nil {
		return fail(err)
	}

	certFile, err = tempName()
	if err != nil {
		return fail(err)
	}

	csrPEM, keyPEM, err := csr.ParseRequest(req)
	if err != nil {
		return fail(err)
	}

	if err = ioutil.WriteFile(keyFile, keyPEM, 0644); err != nil {
		return fail(err)
	}

	priv, err := helpers.ParsePrivateKeyPEM(keyPEM)
	if err != nil {
		return fail(err)
	}

	cert, err := selfsign.Sign(priv, csrPEM, config.DefaultConfig())
	if err != nil {
		return fail(err)
	}

	if err = ioutil.WriteFile(certFile, cert, 0644); err != nil {
		return fail(err)
	}

	return
}
Ejemplo n.º 8
0
// NewSigner creates a new Signer directly from a
// private key and certificate, with optional policy.
func NewSigner(priv crypto.Signer, cert *x509.Certificate, sigAlgo x509.SignatureAlgorithm, policy *config.Signing) (*Signer, error) {
	if policy == nil {
		policy = &config.Signing{
			Profiles: map[string]*config.SigningProfile{},
			Default:  config.DefaultConfig()}
	}

	if !policy.Valid() {
		return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
	}

	return &Signer{
		ca:      cert,
		priv:    priv,
		sigAlgo: sigAlgo,
		policy:  policy,
	}, nil
}
Ejemplo n.º 9
0
func TestRebundleExpiring(t *testing.T) {
	// make a policy that generate a cert expires in one hour.
	expiry := 1 * time.Hour
	policy := &config.Signing{
		Profiles: map[string]*config.SigningProfile{
			"expireIn1Hour": &config.SigningProfile{
				Usage:  []string{"cert sign"},
				Expiry: expiry,
				CA:     true,
			},
		},
		Default: config.DefaultConfig(),
	}
	// Generate a intermediate cert that expires in one hour.
	expiringPEM := createInterCert(t, interL1CSR, policy, "expireIn1Hour")
	rootBundlePEM, _ := ioutil.ReadFile(testCFSSLRootBundle)

	// Use the expiring intermediate to initiate a bundler.
	bundler, err := NewBundlerFromPEM(rootBundlePEM, expiringPEM)
	if err != nil {
		t.Fatalf("bundle failed. %s", err.Error())
	}
	newBundle, err := bundler.BundleFromPEMorDER(expiredBundlePEM, nil, Optimal, "")
	if err != nil {
		t.Fatalf("Re-bundle failed. %s", err.Error())
	}
	// Check the bundle content.
	newChain := newBundle.Chain
	if len(newChain) != 2 {
		t.Fatalf("Expected bundle chain length is 2. Got %d.", len(newChain))
	}
	// The status must be {Code: ExpiringBit is set, IsRebundled:true, ExpiringSKIs:{"8860BA18A477B841041BD5EF7751C25B14BA203F"}}
	if len(newBundle.Status.ExpiringSKIs) != 1 || !newBundle.Status.IsRebundled || newBundle.Status.Code&errors.BundleExpiringBit == 0 {
		t.Fatal("Rebundle Status is incorrect.")
	}
	expectedSKI := "8860BA18A477B841041BD5EF7751C25B14BA203F"
	if newBundle.Status.ExpiringSKIs[0] != expectedSKI {
		t.Fatalf("Expected expiring cert SKI is %s, got %s\n", expectedSKI, newBundle.Status.ExpiringSKIs[0])
	}

}
Ejemplo n.º 10
0
func TestDefaultSign(t *testing.T) {
	csrBytes, err := ioutil.ReadFile(csrFile)
	if err != nil {
		t.Fatal(err)
	}
	keyBytes, err := ioutil.ReadFile(keyFile)
	if err != nil {
		t.Fatal(err)
	}

	priv, err := helpers.ParsePrivateKeyPEM(keyBytes)
	if err != nil {
		t.Fatal(err)
	}

	profile := config.DefaultConfig()
	profile.Expiry = 10 * time.Hour

	_, err = Sign(priv, csrBytes, profile)
	if err != nil {
		t.Fatal(err)
	}
}
Ejemplo n.º 11
0
Archivo: signer.go Proyecto: kalw/cfssl
// NewSigner generates a new certificate signer using the certificate
// authority certificate and private key and Signing config for signing. caFile should
// contain the CA's certificate, and the cakeyFile should contain the
// private key. Both must be PEM-encoded.
func NewSigner(caFile, cakeyFile string, policy *config.Signing) (*Signer, error) {
	if policy == nil {
		policy = &config.Signing{
			Profiles: map[string]*config.SigningProfile{},
			Default:  config.DefaultConfig(),
		}
	}

	if !policy.Valid() {
		return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy, errors.New("invalid policy"))
	}

	log.Debug("Loading CA: ", caFile)
	ca, err := ioutil.ReadFile(caFile)
	if err != nil {
		return nil, err
	}
	log.Debug("Loading CA key: ", cakeyFile)
	cakey, err := ioutil.ReadFile(cakeyFile)
	if err != nil {
		return nil, err
	}

	parsedCa, err := helpers.ParseCertificatePEM(ca)
	if err != nil {
		return nil, err
	}

	priv, err := helpers.ParsePrivateKeyPEM(cakey)
	if err != nil {

		return nil, err
	}

	return &Signer{parsedCa, priv, policy, DefaultSigAlgo(priv)}, nil
}
Ejemplo n.º 12
0
func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Duration, caCertFile, caKeyFile string, approver AutoApprover) (*CertificateController, error) {
	// Send events to the apiserver
	eventBroadcaster := record.NewBroadcaster()
	eventBroadcaster.StartLogging(glog.Infof)
	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")})

	// Configure cfssl signer
	// TODO: support non-default policy and remote/pkcs11 signing
	policy := &config.Signing{
		Default: config.DefaultConfig(),
	}
	ca, err := local.NewSignerFromFile(caCertFile, caKeyFile, policy)
	if err != nil {
		return nil, err
	}

	cc := &CertificateController{
		kubeClient: kubeClient,
		queue:      workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "certificate"),
		signer:     ca,
		approver:   approver,
	}

	// Manage the addition/update of certificate requests
	cc.csrStore.Store, cc.csrController = cache.NewInformer(
		&cache.ListWatch{
			ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
				return cc.kubeClient.Certificates().CertificateSigningRequests().List(options)
			},
			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
				return cc.kubeClient.Certificates().CertificateSigningRequests().Watch(options)
			},
		},
		&certificates.CertificateSigningRequest{},
		syncPeriod,
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				csr := obj.(*certificates.CertificateSigningRequest)
				glog.V(4).Infof("Adding certificate request %s", csr.Name)
				cc.enqueueCertificateRequest(obj)
			},
			UpdateFunc: func(old, new interface{}) {
				oldCSR := old.(*certificates.CertificateSigningRequest)
				glog.V(4).Infof("Updating certificate request %s", oldCSR.Name)
				cc.enqueueCertificateRequest(new)
			},
			DeleteFunc: func(obj interface{}) {
				csr, ok := obj.(*certificates.CertificateSigningRequest)
				if !ok {
					tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
					if !ok {
						glog.V(2).Infof("Couldn't get object from tombstone %#v", obj)
						return
					}
					csr, ok = tombstone.Obj.(*certificates.CertificateSigningRequest)
					if !ok {
						glog.V(2).Infof("Tombstone contained object that is not a CSR: %#v", obj)
						return
					}
				}
				glog.V(4).Infof("Deleting certificate request %s", csr.Name)
				cc.enqueueCertificateRequest(obj)
			},
		},
	)
	cc.syncHandler = cc.maybeSignCertificate
	return cc, nil
}
Ejemplo n.º 13
0
func selfSignMain(args []string, c cli.Config) (err error) {
	if c.Hostname == "" && !c.IsCA {
		c.Hostname, args, err = cli.PopFirstArgument(args)
		if err != nil {
			return
		}
	}

	csrFile, args, err := cli.PopFirstArgument(args)
	if err != nil {
		return
	}

	csrFileBytes, err := cli.ReadStdin(csrFile)
	if err != nil {
		return
	}

	var req = csr.New()
	err = json.Unmarshal(csrFileBytes, req)
	if err != nil {
		return
	}

	var key, csrPEM []byte
	g := &csr.Generator{Validator: genkey.Validator}
	csrPEM, key, err = g.ProcessRequest(req)
	if err != nil {
		key = nil
		return
	}

	priv, err := helpers.ParsePrivateKeyPEM(key)
	if err != nil {
		key = nil
		return
	}

	var profile *config.SigningProfile

	// If there is a config, use its signing policy. Otherwise, leave policy == nil
	// and NewSigner will use DefaultConfig().
	if c.CFG != nil {
		if c.Profile != "" && c.CFG.Signing.Profiles != nil {
			profile = c.CFG.Signing.Profiles[c.Profile]
		}
	}

	if profile == nil {
		profile = config.DefaultConfig()
		profile.Expiry = 2190 * time.Hour
	}

	cert, err := selfsign.Sign(priv, csrPEM, profile)
	if err != nil {
		key = nil
		priv = nil
		return
	}

	fmt.Fprintf(os.Stderr, `*** WARNING ***

Self-signed certificates are dangerous. Use this self-signed
certificate at your own risk.

It is strongly recommended that these certificates NOT be used
in production.

*** WARNING ***

`)
	cli.PrintCert(key, csrPEM, cert)
	return
}