Ejemplo n.º 1
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.º 2
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.º 3
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.º 4
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.º 5
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.CertificateRequest
	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
}