// helper functions func newConfig(t *testing.T, configBytes []byte) *config.Config { conf, err := config.LoadConfig([]byte(configBytes)) if err != nil { t.Fatal("config loading error:", err) } if !conf.Valid() { t.Fatal("config is not valid") } return conf }
// 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 cmd.CAConfig, clk clock.Clock, issuerCert string) (*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 } // CFSSL requires processing JSON configs through its own LoadConfig, so we // serialize and then deserialize. cfsslJSON, err := json.Marshal(config.CFSSL) if err != nil { return nil, err } cfsslConfigObj, err := cfsslConfig.LoadConfig(cfsslJSON) if err != nil { return nil, err } // Load the private key, which can be a file or a PKCS#11 key. priv, err := loadKey(config.Key) if err != nil { return nil, err } issuer, err := loadIssuer(issuerCert) if err != nil { return nil, err } signer, err := local.NewSigner(priv, issuer, x509.SHA256WithRSA, cfsslConfigObj.Signing) if err != nil { return nil, err } if config.LifespanOCSP == "" { return nil, errors.New("Config must specify an OCSP lifespan period.") } lifespanOCSP, err := time.ParseDuration(config.LifespanOCSP) 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, priv, lifespanOCSP) if err != nil { return nil, err } ca = &CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, profile: config.Profile, DB: cadb, Prefix: config.SerialPrefix, Clk: clk, log: logger, NotAfter: issuer.NotAfter, } if config.Expiry == "" { return nil, errors.New("Config must specify an expiry period.") } ca.ValidityPeriod, err = time.ParseDuration(config.Expiry) if err != nil { return nil, err } ca.MaxNames = config.MaxNames return ca, nil }
// 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( config cmd.CAConfig, clk clock.Clock, stats statsd.Statter, issuer *x509.Certificate, privateKey crypto.Signer, keyPolicy core.KeyPolicy, ) (*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 } // CFSSL requires processing JSON configs through its own LoadConfig, so we // serialize and then deserialize. cfsslJSON, err := json.Marshal(config.CFSSL) if err != nil { return nil, err } cfsslConfigObj, err := cfsslConfig.LoadConfig(cfsslJSON) if err != nil { return nil, err } signer, err := local.NewSigner(privateKey, issuer, x509.SHA256WithRSA, cfsslConfigObj.Signing) if err != nil { return nil, err } if config.LifespanOCSP == "" { return nil, errors.New("Config must specify an OCSP lifespan period.") } lifespanOCSP, err := time.ParseDuration(config.LifespanOCSP) 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, privateKey, lifespanOCSP) if err != nil { return nil, err } rsaProfile := config.RSAProfile ecdsaProfile := config.ECDSAProfile if config.Profile != "" { if rsaProfile != "" || ecdsaProfile != "" { return nil, errors.New("either specify profile or rsaProfile and ecdsaProfile, but not both") } rsaProfile = config.Profile ecdsaProfile = config.Profile } if rsaProfile == "" || ecdsaProfile == "" { return nil, errors.New("must specify rsaProfile and ecdsaProfile") } ca = &CertificateAuthorityImpl{ signer: signer, ocspSigner: ocspSigner, rsaProfile: rsaProfile, ecdsaProfile: ecdsaProfile, prefix: config.SerialPrefix, clk: clk, log: logger, stats: stats, notAfter: issuer.NotAfter, hsmFaultTimeout: config.HSMFaultTimeout.Duration, keyPolicy: keyPolicy, } if config.Expiry == "" { return nil, errors.New("Config must specify an expiry period.") } ca.validityPeriod, err = time.ParseDuration(config.Expiry) if err != nil { return nil, err } ca.maxNames = config.MaxNames return ca, nil }