// 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 }
// 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 }
func newUniversalSigner(root Root, policy *config.Signing) (*Signer, error) { ls, err := newLocalSigner(root, policy) if err != nil { return nil, err } rs, err := remote.NewSigner(policy) if err != nil { return nil, err } s := &Signer{ policy: policy, local: ls, remote: rs, } return s, err }
// NewCertificateAuthorityImpl creates a CA that talks to a remote CFSSL // instance. (To use a local signer, simply instantiate CertificateAuthorityImpl // directly.) Communications with the CA are authenticated with MACs, // using CFSSL's authenticated signature scheme. A CA created in this way // issues for a single profile on the remote signer, which is indicated // by name in this constructor. func NewCertificateAuthorityImpl(cadb core.CertificateAuthorityDatabase, config Config) (*CertificateAuthorityImpl, error) { var ca *CertificateAuthorityImpl var err error logger := blog.GetAuditLogger() logger.Notice("Certificate Authority Starting") if config.SerialPrefix <= 0 || config.SerialPrefix >= 256 { err = errors.New("Must have a positive non-zero serial prefix less than 256 for CA.") return nil, err } // Create the remote signer localProfile := cfsslConfig.SigningProfile{ Expiry: time.Hour, // BOGUS: Required by CFSSL, but not used RemoteName: config.Server, // BOGUS: Only used as a flag by CFSSL RemoteServer: config.Server, UseSerialSeq: true, } localProfile.Provider, err = auth.New(config.AuthKey, nil) if err != nil { return nil, err } signer, err := remote.NewSigner(&cfsslConfig.Signing{Default: &localProfile}) if err != nil { return nil, err } issuer, err := loadIssuer(config.IssuerCert) if err != nil { return nil, err } // In test mode, load a private key from a file. // TODO: This should rely on the CFSSL config, to make it easy to use a key // from a file vs an HSM. https://github.com/letsencrypt/boulder/issues/163 issuerKey, err := loadIssuerKey(config.IssuerKey) if err != nil { return nil, err } // Set up our OCSP signer. Note this calls for both the issuer cert and the // OCSP signing cert, which are the same in our case. ocspSigner, err := ocsp.NewSigner(issuer, issuer, issuerKey, time.Hour*24*4) if err != nil { return nil, err } pa := policy.NewPolicyAuthorityImpl() ca = &CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, profile: config.Profile, PA: pa, DB: cadb, Prefix: config.SerialPrefix, log: logger, NotAfter: issuer.NotAfter, } ca.ValidityPeriod, err = time.ParseDuration(config.Expiry) if err != nil { return nil, err } return ca, nil }