Allow PKCS11 config to be loaded from a file.

This allows secret values (PIN) to be separated from the main config.

Part of #1157.

In the process, move the CA constructor in the direction of
https://github.com/letsencrypt/boulder/wiki/Config-plan:

- Make most fields private.
- Take private key and issuer cert as constructor arguments rather than
  constructing them internally.

This allows the CA test to parse the private key and issuer cert once, rather
than once per test case.
This commit is contained in:
Jacob Hoffman-Andrews 2015-11-27 15:12:15 -08:00
parent fab8bec525
commit 3ede9b7223
5 changed files with 165 additions and 122 deletions

View File

@ -14,7 +14,6 @@ import (
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"math/big"
"strings"
"sync"
@ -27,8 +26,6 @@ import (
blog "github.com/letsencrypt/boulder/log"
cfsslConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local"
@ -63,18 +60,18 @@ const (
// OCSP responses.
type CertificateAuthorityImpl struct {
profile string
Signer signer.Signer
OCSPSigner ocsp.Signer
signer signer.Signer
ocspSigner ocsp.Signer
SA core.StorageAuthority
PA core.PolicyAuthority
Publisher core.Publisher
Clk clock.Clock // TODO(jmhodges): should be private, like log
clk clock.Clock // TODO(jmhodges): should be private, like log
log *blog.AuditLogger
stats statsd.Statter
Prefix int // Prepended to the serial number
ValidityPeriod time.Duration
NotAfter time.Time
MaxNames int
prefix int // Prepended to the serial number
validityPeriod time.Duration
notAfter time.Time
maxNames int
hsmFaultLock sync.Mutex
hsmFaultLastObserved time.Time
@ -87,7 +84,13 @@ type CertificateAuthorityImpl struct {
// 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, issuerCert string) (*CertificateAuthorityImpl, error) {
func NewCertificateAuthorityImpl(
config cmd.CAConfig,
clk clock.Clock,
stats statsd.Statter,
issuer *x509.Certificate,
privateKey crypto.Signer,
) (*CertificateAuthorityImpl, error) {
var ca *CertificateAuthorityImpl
var err error
logger := blog.GetAuditLogger()
@ -109,18 +112,7 @@ func NewCertificateAuthorityImpl(config cmd.CAConfig, clk clock.Clock, stats sta
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 := core.LoadCert(issuerCert)
if err != nil {
return nil, err
}
signer, err := local.NewSigner(priv, issuer, x509.SHA256WithRSA, cfsslConfigObj.Signing)
signer, err := local.NewSigner(privateKey, issuer, x509.SHA256WithRSA, cfsslConfigObj.Signing)
if err != nil {
return nil, err
}
@ -135,61 +127,36 @@ func NewCertificateAuthorityImpl(config cmd.CAConfig, clk clock.Clock, stats sta
// 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)
ocspSigner, err := ocsp.NewSigner(issuer, issuer, privateKey, lifespanOCSP)
if err != nil {
return nil, err
}
ca = &CertificateAuthorityImpl{
Signer: signer,
OCSPSigner: ocspSigner,
signer: signer,
ocspSigner: ocspSigner,
profile: config.Profile,
Prefix: config.SerialPrefix,
Clk: clk,
prefix: config.SerialPrefix,
clk: clk,
log: logger,
stats: stats,
NotAfter: issuer.NotAfter,
notAfter: issuer.NotAfter,
hsmFaultTimeout: config.HSMFaultTimeout.Duration,
}
if config.Expiry == "" {
return nil, errors.New("Config must specify an expiry period.")
}
ca.ValidityPeriod, err = time.ParseDuration(config.Expiry)
ca.validityPeriod, err = time.ParseDuration(config.Expiry)
if err != nil {
return nil, err
}
ca.MaxNames = config.MaxNames
ca.maxNames = config.MaxNames
return ca, nil
}
func loadKey(keyConfig cmd.KeyConfig) (priv crypto.Signer, err error) {
if keyConfig.File != "" {
var keyBytes []byte
keyBytes, err = ioutil.ReadFile(keyConfig.File)
if err != nil {
return nil, fmt.Errorf("Could not read key file %s", keyConfig.File)
}
priv, err = helpers.ParsePrivateKeyPEM(keyBytes)
return
}
pkcs11Config := keyConfig.PKCS11
if pkcs11Config.Module == "" ||
pkcs11Config.TokenLabel == "" ||
pkcs11Config.PIN == "" ||
pkcs11Config.PrivateKeyLabel == "" {
err = fmt.Errorf("Missing a field in pkcs11Config %#v", pkcs11Config)
return
}
priv, err = pkcs11key.New(pkcs11Config.Module,
pkcs11Config.TokenLabel, pkcs11Config.PIN, pkcs11Config.PrivateKeyLabel)
return
}
// checkHSMFault checks whether there has been an HSM fault observed within the
// timeout window. CA methods that use the HSM should call this method right
// away, to minimize the performance impact of HSM outages.
@ -202,7 +169,7 @@ func (ca *CertificateAuthorityImpl) checkHSMFault() error {
return nil
}
now := ca.Clk.Now()
now := ca.clk.Now()
timeout := ca.hsmFaultLastObserved.Add(ca.hsmFaultTimeout)
if now.Before(timeout) {
err := core.ServiceUnavailableError("HSM is unavailable")
@ -221,7 +188,7 @@ func (ca *CertificateAuthorityImpl) noteHSMFault(err error) {
if err != nil {
ca.stats.Inc(metricHSMFaultObserved, 1, 1.0)
ca.hsmFaultLastObserved = ca.Clk.Now()
ca.hsmFaultLastObserved = ca.clk.Now()
}
return
}
@ -246,7 +213,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(xferObj core.OCSPSigningRequest
RevokedAt: xferObj.RevokedAt,
}
ocspResponse, err := ca.OCSPSigner.Sign(signRequest)
ocspResponse, err := ca.ocspSigner.Sign(signRequest)
ca.noteHSMFault(err)
return ocspResponse, err
}
@ -307,8 +274,8 @@ func (ca *CertificateAuthorityImpl) IssueCertificate(csr x509.CertificateRequest
// Collapse any duplicate names. Note that this operation may re-order the names
hostNames = core.UniqueLowerNames(hostNames)
if ca.MaxNames > 0 && len(hostNames) > ca.MaxNames {
err = core.MalformedRequestError(fmt.Sprintf("Certificate request has %d > %d names", len(hostNames), ca.MaxNames))
if ca.maxNames > 0 && len(hostNames) > ca.maxNames {
err = core.MalformedRequestError(fmt.Sprintf("Certificate request has %d names, maximum is %d.", len(hostNames), ca.maxNames))
ca.log.WarningErr(err)
return emptyCert, err
}
@ -331,9 +298,9 @@ func (ca *CertificateAuthorityImpl) IssueCertificate(csr x509.CertificateRequest
}
}
notAfter := ca.Clk.Now().Add(ca.ValidityPeriod)
notAfter := ca.clk.Now().Add(ca.validityPeriod)
if ca.NotAfter.Before(notAfter) {
if ca.notAfter.Before(notAfter) {
err = core.InternalServerError("Cannot issue a certificate that expires after the intermediate certificate.")
// AUDIT[ Certificate Requests ] 11917fa4-10ef-4e0d-9105-bacbe7836a3c
ca.log.AuditErr(err)
@ -349,7 +316,7 @@ func (ca *CertificateAuthorityImpl) IssueCertificate(csr x509.CertificateRequest
// We want 136 bits of random number, plus an 8-bit instance id prefix.
const randBits = 136
serialBytes := make([]byte, randBits/8+1)
serialBytes[0] = byte(ca.Prefix)
serialBytes[0] = byte(ca.prefix)
_, err = rand.Read(serialBytes[1:])
if err != nil {
err = core.InternalServerError(err.Error())
@ -372,7 +339,7 @@ func (ca *CertificateAuthorityImpl) IssueCertificate(csr x509.CertificateRequest
Serial: serialBigInt,
}
certPEM, err := ca.Signer.Sign(req)
certPEM, err := ca.signer.Sign(req)
ca.noteHSMFault(err)
if err != nil {
err = core.InternalServerError(err.Error())

View File

@ -7,6 +7,7 @@ package ca
import (
"bytes"
"crypto"
"crypto/x509"
"encoding/asn1"
"fmt"
@ -16,6 +17,7 @@ import (
"time"
cfsslConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers"
ocspConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/jmhodges/clock"
"github.com/letsencrypt/boulder/cmd"
@ -116,6 +118,21 @@ type testCtx struct {
cleanUp func()
}
var caKey crypto.Signer
var caCert *x509.Certificate
func init() {
var err error
caKey, err = helpers.ParsePrivateKeyPEM(mustRead(caKeyFile))
if err != nil {
panic(fmt.Sprintf("Unable to parse %s: %s", caKeyFile, err))
}
caCert, err = core.LoadCert(caCertFile)
if err != nil {
panic(fmt.Sprintf("Unable to parse %s: %s", caCertFile, err))
}
}
func setup(t *testing.T) *testCtx {
// Create an SA
dbMap, err := sa.NewDbMap(vars.DBConnSA)
@ -146,11 +163,8 @@ func setup(t *testing.T) *testCtx {
// Create a CA
caConfig := cmd.CAConfig{
Profile: profileName,
SerialPrefix: 17,
Key: cmd.KeyConfig{
File: caKeyFile,
},
Profile: profileName,
SerialPrefix: 17,
Expiry: "8760h",
LifespanOCSP: "45m",
MaxNames: 2,
@ -193,7 +207,15 @@ func setup(t *testing.T) *testCtx {
stats := mocks.NewStatter()
return &testCtx{ssa, caConfig, reg, pa, fc, &stats, cleanUp}
return &testCtx{
ssa,
caConfig,
reg,
pa,
fc,
&stats,
cleanUp,
}
}
func TestFailNoSerial(t *testing.T) {
@ -201,14 +223,14 @@ func TestFailNoSerial(t *testing.T) {
defer ctx.cleanUp()
ctx.caConfig.SerialPrefix = 0
_, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
_, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
test.AssertError(t, err, "CA should have failed with no SerialPrefix")
}
func TestIssueCertificate(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
@ -285,7 +307,7 @@ func TestIssueCertificate(t *testing.T) {
func TestRejectNoName(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
@ -302,7 +324,7 @@ func TestRejectNoName(t *testing.T) {
func TestRejectTooManyNames(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
@ -319,7 +341,7 @@ func TestRejectTooManyNames(t *testing.T) {
func TestDeduplication(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
@ -343,7 +365,7 @@ func TestDeduplication(t *testing.T) {
func TestRejectValidityTooLong(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
@ -351,7 +373,7 @@ func TestRejectValidityTooLong(t *testing.T) {
// Test that the CA rejects CSRs that would expire after the intermediate cert
csr, _ := x509.ParseCertificateRequest(NoCNCSR)
ca.NotAfter = ctx.fc.Now()
ca.notAfter = ctx.fc.Now()
_, err = ca.IssueCertificate(*csr, 1)
test.AssertEquals(t, err.Error(), "Cannot issue a certificate that expires after the intermediate certificate.")
_, ok := err.(core.InternalServerError)
@ -361,7 +383,7 @@ func TestRejectValidityTooLong(t *testing.T) {
func TestShortKey(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -377,7 +399,7 @@ func TestShortKey(t *testing.T) {
func TestRejectBadAlgorithm(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -394,7 +416,7 @@ func TestCapitalizedLetters(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ctx.caConfig.MaxNames = 3
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -415,7 +437,7 @@ func TestHSMFaultTimeout(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCertFile)
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, ctx.stats, caCert, caKey)
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -429,13 +451,13 @@ func TestHSMFaultTimeout(t *testing.T) {
}
// Swap in a bad signer
goodSigner := ca.Signer
goodSigner := ca.signer
badHSMErrorMessage := "This is really serious. You should wait"
badSigner := mocks.BadHSMSigner(badHSMErrorMessage)
badOCSPSigner := mocks.BadHSMOCSPSigner(badHSMErrorMessage)
// Cause the CA to enter the HSM fault condition
ca.Signer = badSigner
ca.signer = badSigner
_, err = ca.IssueCertificate(*csr, ctx.reg.ID)
test.AssertError(t, err, "CA failed to return HSM error")
test.AssertEquals(t, err.Error(), badHSMErrorMessage)
@ -450,7 +472,7 @@ func TestHSMFaultTimeout(t *testing.T) {
test.AssertEquals(t, err.Error(), "HSM is unavailable")
// Swap in a good signer and move the clock forward to clear the fault
ca.Signer = goodSigner
ca.signer = goodSigner
ctx.fc.Add(ca.hsmFaultTimeout)
ctx.fc.Add(10 * time.Second)
@ -460,7 +482,7 @@ func TestHSMFaultTimeout(t *testing.T) {
_, err = ca.GenerateOCSP(ocspRequest)
// Check that GenerateOCSP can also trigger an HSM failure, in the same way
ca.OCSPSigner = badOCSPSigner
ca.ocspSigner = badOCSPSigner
_, err = ca.GenerateOCSP(ocspRequest)
test.AssertError(t, err, "CA failed to return HSM error")
test.AssertEquals(t, err.Error(), badHSMErrorMessage)

View File

@ -6,10 +6,18 @@
package main
import (
"crypto"
"encoding/json"
"fmt"
"io/ioutil"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/jmhodges/clock"
"github.com/letsencrypt/boulder/ca"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/core"
blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/policy"
"github.com/letsencrypt/boulder/rpc"
@ -18,6 +26,40 @@ import (
const clientName = "CA"
func loadPrivateKey(keyConfig cmd.KeyConfig) (crypto.Signer, error) {
if keyConfig.File != "" {
keyBytes, err := ioutil.ReadFile(keyConfig.File)
if err != nil {
return nil, fmt.Errorf("Could not read key file %s", keyConfig.File)
}
return helpers.ParsePrivateKeyPEM(keyBytes)
}
var pkcs11Config *pkcs11key.Config
if keyConfig.ConfigFile != "" {
contents, err := ioutil.ReadFile(keyConfig.ConfigFile)
if err != nil {
return nil, err
}
pkcs11Config = new(pkcs11key.Config)
err = json.Unmarshal(contents, pkcs11Config)
if err != nil {
return nil, err
}
} else {
pkcs11Config = keyConfig.PKCS11
}
if pkcs11Config.Module == "" ||
pkcs11Config.TokenLabel == "" ||
pkcs11Config.PIN == "" ||
pkcs11Config.PrivateKeyLabel == "" {
return nil, fmt.Errorf("Missing a field in pkcs11Config %#v", pkcs11Config)
}
return pkcs11key.New(pkcs11Config.Module,
pkcs11Config.TokenLabel, pkcs11Config.PIN, pkcs11Config.PrivateKeyLabel)
}
func main() {
app := cmd.NewAppShell("boulder-ca", "Handles issuance operations")
app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) {
@ -37,7 +79,18 @@ func main() {
pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist, c.PA.Challenges)
cmd.FailOnError(err, "Couldn't create PA")
cai, err := ca.NewCertificateAuthorityImpl(c.CA, clock.Default(), stats, c.Common.IssuerCert)
priv, err := loadPrivateKey(c.CA.Key)
cmd.FailOnError(err, "Couldn't load private key")
issuer, err := core.LoadCert(c.Common.IssuerCert)
cmd.FailOnError(err, "Couldn't load issuer cert")
cai, err := ca.NewCertificateAuthorityImpl(
c.CA,
clock.Default(),
stats,
issuer,
priv)
cmd.FailOnError(err, "Failed to create CA impl")
cai.PA = pa

View File

@ -12,6 +12,7 @@ import (
"time"
cfsslConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key"
"github.com/letsencrypt/boulder/core"
"github.com/letsencrypt/boulder/publisher"
"github.com/letsencrypt/boulder/va"
@ -263,16 +264,10 @@ func (pc *PAConfig) SetDefaultChallengesIfEmpty() {
// KeyConfig should contain either a File path to a PEM-format private key,
// or a PKCS11Config defining how to load a module for an HSM.
type KeyConfig struct {
File string
PKCS11 PKCS11Config
}
// PKCS11Config defines how to load a module for an HSM.
type PKCS11Config struct {
Module string
TokenLabel string
PIN string
PrivateKeyLabel string
// A file from which a pkcs11key.Config will be read and parsed, if present
ConfigFile string
File string
PKCS11 *pkcs11key.Config
}
// TLSConfig reprents certificates and a key for authenticated TLS.

View File

@ -20,8 +20,6 @@ import (
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
cfsslConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/jmhodges/clock"
jose "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
"github.com/letsencrypt/boulder/ca"
@ -180,20 +178,26 @@ func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAut
caKey, _ := x509.ParsePKCS1PrivateKey(caKeyPEM.Bytes)
caCertPEM, _ := pem.Decode([]byte(CAcertPEM))
caCert, _ := x509.ParseCertificate(caCertPEM.Bytes)
basicPolicy := &cfsslConfig.Signing{
Default: &cfsslConfig.SigningProfile{
Usage: []string{"server auth", "client auth"},
Expiry: 1 * time.Hour,
CSRWhitelist: &cfsslConfig.CSRWhitelist{
PublicKey: true,
PublicKeyAlgorithm: true,
SignatureAlgorithm: true,
DNSNames: true,
cfsslC := cfsslConfig.Config{
Signing: &cfsslConfig.Signing{
Default: &cfsslConfig.SigningProfile{
Usage: []string{"server auth", "client auth"},
ExpiryString: "1h",
CSRWhitelist: &cfsslConfig.CSRWhitelist{
PublicKey: true,
PublicKeyAlgorithm: true,
SignatureAlgorithm: true,
DNSNames: true,
},
},
},
}
signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, basicPolicy)
ocspSigner, _ := ocsp.NewSigner(caCert, caCert, caKey, time.Hour)
caConf := cmd.CAConfig{
SerialPrefix: 10,
LifespanOCSP: "1h",
Expiry: "1h",
CFSSL: cfsslC,
}
paDbMap, err := sa.NewDbMap(vars.DBConnPolicy)
if err != nil {
t.Fatalf("Failed to create dbMap: %s", err)
@ -201,16 +205,19 @@ func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAut
policyDBCleanUp := test.ResetPolicyTestDatabase(t)
pa, err := policy.NewPolicyAuthorityImpl(paDbMap, false, SupportedChallenges)
test.AssertNotError(t, err, "Couldn't create PA")
ca := ca.CertificateAuthorityImpl{
Signer: signer,
OCSPSigner: ocspSigner,
SA: ssa,
PA: pa,
ValidityPeriod: time.Hour * 2190,
NotAfter: time.Now().Add(time.Hour * 8761),
Clk: fc,
Publisher: &mocks.Publisher{},
}
stats, _ := statsd.NewNoopClient()
ca, err := ca.NewCertificateAuthorityImpl(
caConf,
fc,
stats,
caCert,
caKey)
test.AssertNotError(t, err, "Couldn't create CA")
ca.SA = ssa
ca.PA = pa
ca.Publisher = &mocks.Publisher{}
cleanUp := func() {
saDBCleanUp()
policyDBCleanUp()
@ -224,7 +231,6 @@ func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAut
InitialIP: net.ParseIP("3.2.3.3"),
})
stats, _ := statsd.NewNoopClient()
ra := NewRegistrationAuthorityImpl(fc,
blog.GetAuditLogger(),
stats,
@ -237,7 +243,7 @@ func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAut
}, 1)
ra.SA = ssa
ra.VA = va
ra.CA = &ca
ra.CA = ca
ra.PA = pa
ra.DNSResolver = &mocks.DNSResolver{}