CA: Choose issuer cert based on CSR's PublicKeyAlgorithm (#5042)

The ca's configuration already has support for containing multiple
issuers. However, when it comes time to actually sign a (pre)cert,
it always uses the defaultIssuer.

This change has the ca instead choose which issuer to use based
on the PublicKeyAlgorithm requested in the CSR (or, for final cert
issuances, based on the PublicKeyAlgorithm in the precert).

This will allow us to use our RSA issuers to sign certificates for
users who aren't ready to switch to ECDSA, while immediately switching
to our new ECDSA chain for subscribers who want to use it.

Fixed #5027
This commit is contained in:
Aaron Gable 2020-08-31 16:13:31 -07:00 committed by GitHub
parent 050a60f810
commit 00133dc6c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 178 additions and 147 deletions

176
ca/ca.go
View File

@ -111,17 +111,25 @@ const (
certType = certificateType("certificate")
)
// Three maps of keys to internalIssuers. Lookup by PublicKeyAlgorithm is
// useful for determining which issuer to use to sign a given (pre)cert, based
// on its PublicKeyAlgorithm. Lookup by CommonName is useful for determining
// which issuer to use to sign an OCSP response, based on the cert's
// Issuer CN. Lookup by ID is useful for the same functionality, in cases
// where features.StoreIssuerInfo is true and the OCSP request is identified
// by Serial and IssuerID rather than by the full cert.
type issuerMaps struct {
byAlg map[x509.PublicKeyAlgorithm]*internalIssuer
byName map[string]*internalIssuer
byID map[int64]*internalIssuer
}
// CertificateAuthorityImpl represents a CA that signs certificates, CRLs, and
// OCSP responses.
type CertificateAuthorityImpl struct {
rsaProfile string
ecdsaProfile string
// A map from issuer cert common name to an internalIssuer struct
issuers map[string]*internalIssuer
// A map from issuer ID to internalIssuer
idToIssuer map[int64]*internalIssuer
// The common name of the default issuer cert
defaultIssuer *internalIssuer
rsaProfile string
ecdsaProfile string
issuers issuerMaps
sa certificateStorage
pa core.PolicyAuthority
keyPolicy goodkey.KeyPolicy
@ -164,54 +172,82 @@ type internalIssuer struct {
boulderSigner *bsigner.Signer
}
func makeInternalIssuers(issuers []bsigner.Config, lifespanOCSP time.Duration) (map[string]*internalIssuer, error) {
internalIssuers := make(map[string]*internalIssuer, len(issuers))
func makeInternalIssuers(issuers []bsigner.Config, lifespanOCSP time.Duration) (issuerMaps, error) {
issuersByAlg := make(map[x509.PublicKeyAlgorithm]*internalIssuer, 2)
issuersByName := make(map[string]*internalIssuer, len(issuers))
issuersByID := make(map[int64]*internalIssuer, len(issuers))
for _, issuer := range issuers {
signer, err := bsigner.NewSigner(issuer)
if err != nil {
return nil, err
return issuerMaps{}, err
}
if internalIssuers[issuer.Issuer.Subject.CommonName] != nil {
return nil, errors.New("Multiple issuer certs with the same CommonName are not supported")
}
internalIssuers[issuer.Issuer.Subject.CommonName] = &internalIssuer{
ii := &internalIssuer{
cert: issuer.Issuer,
ocspSigner: issuer.Signer,
boulderSigner: signer,
}
if issuer.Profile.UseForRSALeaves {
if issuersByAlg[x509.RSA] != nil {
return issuerMaps{}, errors.New("Multiple issuer certs for RSA are not allowed")
}
issuersByAlg[x509.RSA] = ii
}
if issuer.Profile.UseForECDSALeaves {
if issuersByAlg[x509.ECDSA] != nil {
return issuerMaps{}, errors.New("Multiple issuer certs for ECDSA are not allowed")
}
issuersByAlg[x509.ECDSA] = ii
}
if issuersByName[issuer.Issuer.Subject.CommonName] != nil {
return issuerMaps{}, errors.New("Multiple issuer certs with the same CommonName are not supported")
}
issuersByName[issuer.Issuer.Subject.CommonName] = ii
issuersByID[idForIssuer(issuer.Issuer)] = ii
}
return internalIssuers, nil
return issuerMaps{issuersByAlg, issuersByName, issuersByID}, nil
}
func makeCFSSLInternalIssuers(
issuers []Issuer,
policy *cfsslConfig.Signing,
lifespanOCSP time.Duration,
) (map[string]*internalIssuer, error) {
func makeCFSSLInternalIssuers(issuers []Issuer, policy *cfsslConfig.Signing, lifespanOCSP time.Duration) (issuerMaps, error) {
if len(issuers) == 0 {
return nil, errors.New("No issuers specified.")
return issuerMaps{}, errors.New("No issuers specified.")
}
internalIssuers := make(map[string]*internalIssuer)
for _, iss := range issuers {
issuersByAlg := make(map[x509.PublicKeyAlgorithm]*internalIssuer, len(issuers))
issuersByName := make(map[string]*internalIssuer, len(issuers))
issuersByID := make(map[int64]*internalIssuer, len(issuers))
for idx, iss := range issuers {
if iss.Cert == nil || iss.Signer == nil {
return nil, errors.New("Issuer with nil cert or signer specified.")
return issuerMaps{}, errors.New("Issuer with nil cert or signer specified.")
}
cfsslSigner, err := local.NewSigner(iss.Signer, iss.Cert, x509.SHA256WithRSA, policy)
if err != nil {
return nil, err
return issuerMaps{}, err
}
cn := iss.Cert.Subject.CommonName
if issuersByName[cn] != nil {
return issuerMaps{}, errors.New("Multiple issuer certs with the same CommonName are not supported")
}
cn := iss.Cert.Subject.CommonName
if internalIssuers[cn] != nil {
return nil, errors.New("Multiple issuer certs with the same CommonName are not supported")
}
internalIssuers[cn] = &internalIssuer{
ii := &internalIssuer{
cert: iss.Cert,
cfsslSigner: cfsslSigner,
ocspSigner: iss.Signer,
}
// Rather than reading a config to pick which issuer to use for each alg,
// just fall back to our old behavior of "the first issuer is used by default
// for everything". Ensure that the first issuer is an RSA key so that signing
// with x509.SHA256WithRSA doesn't break.
if idx == 0 {
if iss.Cert.PublicKeyAlgorithm != x509.RSA {
return issuerMaps{}, errors.New("Default (first) issuer must be RSA when using CFSSL")
}
issuersByAlg[x509.RSA] = ii
issuersByAlg[x509.ECDSA] = ii
}
issuersByName[cn] = ii
issuersByID[idForIssuer(iss.Cert)] = ii
}
return internalIssuers, nil
return issuerMaps{issuersByAlg, issuersByName, issuersByID}, nil
}
// idForIssuer generates a stable ID for an issuer certificate. This
@ -245,17 +281,15 @@ func NewCertificateAuthorityImpl(
return nil, err
}
var internalIssuers map[string]*internalIssuer
var defaultIssuer *internalIssuer
var issuers issuerMaps
// rsaProfile and ecdsaProfile are unused when using the boulder signer
// instead of the CFSSL signer
var rsaProfile, ecdsaProfile string
if features.Enabled(features.NonCFSSLSigner) {
internalIssuers, err = makeInternalIssuers(boulderIssuers, config.LifespanOCSP.Duration)
issuers, err = makeInternalIssuers(boulderIssuers, config.LifespanOCSP.Duration)
if err != nil {
return nil, err
}
defaultIssuer = internalIssuers[boulderIssuers[0].Issuer.Subject.CommonName]
} else {
// CFSSL requires processing JSON configs through its own LoadConfig, so we
// serialize and then deserialize.
@ -278,7 +312,7 @@ func NewCertificateAuthorityImpl(
}
}
internalIssuers, err = makeCFSSLInternalIssuers(
issuers, err = makeCFSSLInternalIssuers(
cfsslIssuers,
cfsslConfigObj.Signing,
config.LifespanOCSP.Duration)
@ -291,7 +325,6 @@ func NewCertificateAuthorityImpl(
if rsaProfile == "" || ecdsaProfile == "" {
return nil, errors.New("must specify rsaProfile and ecdsaProfile")
}
defaultIssuer = internalIssuers[cfsslIssuers[0].Cert.Subject.CommonName]
}
csrExtensionCount := prometheus.NewCounterVec(
@ -335,8 +368,7 @@ func NewCertificateAuthorityImpl(
ca = &CertificateAuthorityImpl{
sa: sa,
pa: pa,
issuers: internalIssuers,
defaultIssuer: defaultIssuer,
issuers: issuers,
rsaProfile: rsaProfile,
ecdsaProfile: ecdsaProfile,
prefix: config.SerialPrefix,
@ -352,12 +384,6 @@ func NewCertificateAuthorityImpl(
signErrorCounter: signErrorCounter,
}
ca.idToIssuer = make(map[int64]*internalIssuer)
for _, ii := range ca.issuers {
id := idForIssuer(ii.cert)
ca.idToIssuer[id] = ii
}
if config.Expiry == "" {
return nil, errors.New("Config must specify an expiry period.")
}
@ -484,7 +510,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, req *capb.
}
serial = serialInt
var ok bool
issuer, ok = ca.idToIssuer[req.IssuerID]
issuer, ok = ca.issuers.byID[req.IssuerID]
if !ok {
return nil, fmt.Errorf("This CA doesn't have an issuer cert with ID %d", req.IssuerID)
}
@ -497,7 +523,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, req *capb.
serial = cert.SerialNumber
cn := cert.Issuer.CommonName
issuer = ca.issuers[cn]
issuer = ca.issuers.byName[cn]
if issuer == nil {
return nil, fmt.Errorf("This CA doesn't have an issuer cert with CommonName %q", cn)
}
@ -554,7 +580,7 @@ func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
return nil, err
}
precertDER, err := ca.issuePrecertificateInner(ctx, issueReq, serialBigInt, validity)
precertDER, issuer, err := ca.issuePrecertificateInner(ctx, issueReq, serialBigInt, validity)
if err != nil {
return nil, err
}
@ -570,17 +596,13 @@ func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
}
req := &sapb.AddCertificateRequest{
Der: precertDER,
RegID: regID,
Ocsp: ocspResp.Response,
Issued: nowNanos,
Der: precertDER,
RegID: regID,
Ocsp: ocspResp.Response,
Issued: nowNanos,
IssuerID: idForIssuer(issuer.cert),
}
// we currently only use one issuer, in the future when we support multiple
// the issuer will need to be derived from issueReq
issuerID := idForIssuer(ca.defaultIssuer.cert)
req.IssuerID = issuerID
_, err = ca.sa.AddPrecertificate(ctx, req)
if err != nil {
ca.orphanCount.With(prometheus.Labels{"type": "precert"}).Inc()
@ -656,18 +678,23 @@ func (ca *CertificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
scts = append(scts, sct)
}
issuer, ok := ca.issuers.byAlg[precert.PublicKeyAlgorithm]
if !ok {
return nil, berrors.InternalServerError("no issuer found for public key algorithm %s", precert.PublicKeyAlgorithm)
}
var certDER []byte
if features.Enabled(features.NonCFSSLSigner) {
issuanceReq, err := bsigner.RequestFromPrecert(precert, scts)
if err != nil {
return nil, err
}
certDER, err = ca.defaultIssuer.boulderSigner.Issue(issuanceReq)
certDER, err = issuer.boulderSigner.Issue(issuanceReq)
if err != nil {
return nil, err
}
} else {
certPEM, err := ca.defaultIssuer.cfsslSigner.SignFromPrecert(precert, scts)
certPEM, err := issuer.cfsslSigner.SignFromPrecert(precert, scts)
if err != nil {
return nil, err
}
@ -729,10 +756,10 @@ func (ca *CertificateAuthorityImpl) generateSerialNumberAndValidity() (*big.Int,
return serialBigInt, validity, nil
}
func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context, issueReq *capb.IssueCertificateRequest, serialBigInt *big.Int, validity validity) ([]byte, error) {
func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context, issueReq *capb.IssueCertificateRequest, serialBigInt *big.Int, validity validity) ([]byte, *internalIssuer, error) {
csr, err := x509.ParseCertificateRequest(issueReq.Csr)
if err != nil {
return nil, err
return nil, nil, err
}
if err := csrlib.VerifyCSR(
@ -746,20 +773,23 @@ func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
ca.log.AuditErr(err.Error())
// VerifyCSR returns berror instances that can be passed through as-is
// without wrapping.
return nil, err
return nil, nil, err
}
extensions, err := ca.extensionsFromCSR(csr)
if err != nil {
return nil, err
return nil, nil, err
}
issuer := ca.defaultIssuer
issuer, ok := ca.issuers.byAlg[csr.PublicKeyAlgorithm]
if !ok {
return nil, nil, berrors.InternalServerError("no issuer found for public key algorithm %s", csr.PublicKeyAlgorithm)
}
if issuer.cert.NotAfter.Before(validity.NotAfter) {
err = berrors.InternalServerError("cannot issue a certificate that expires after the issuer certificate")
ca.log.AuditErr(err.Error())
return nil, err
return nil, nil, err
}
serialHex := core.SerialToString(serialBigInt)
@ -782,7 +812,7 @@ func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
if err != nil {
err = berrors.InternalServerError("failed to sign certificate: %s", err)
ca.log.AuditErrf("Signing failed: serial=[%s] err=[%v]", serialHex, err)
return nil, err
return nil, nil, err
}
} else {
// Convert the CSR to PEM
@ -800,7 +830,7 @@ func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
default:
err = berrors.InternalServerError("unsupported key type %T", csr.PublicKey)
ca.log.AuditErr(err.Error())
return nil, err
return nil, nil, err
}
// Send the cert off for signing
@ -833,25 +863,25 @@ func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
lintErrsJSON, _ := json.Marshal(lErr.ErrorResults)
ca.log.AuditErrf("Signing failed: serial=[%s] err=[%v] lintErrors=%s",
serialHex, err, string(lintErrsJSON))
return nil, berrors.InternalServerError("failed to sign certificate: %s", err)
return nil, nil, berrors.InternalServerError("failed to sign certificate: %s", err)
}
err = berrors.InternalServerError("failed to sign certificate: %s", err)
ca.log.AuditErrf("Signing failed: serial=[%s] err=[%v]", serialHex, err)
return nil, err
return nil, nil, err
}
if len(certPEM) == 0 {
err = berrors.InternalServerError("no certificate returned by server")
ca.log.AuditErrf("PEM empty from Signer: serial=[%s] err=[%v]", serialHex, err)
return nil, err
return nil, nil, err
}
block, _ := pem.Decode(certPEM)
if block == nil || block.Type != "CERTIFICATE" {
err = berrors.InternalServerError("invalid certificate value returned")
ca.log.AuditErrf("PEM decode error, aborting: serial=[%s] pem=[%s] err=[%v]", serialHex, certPEM, err)
return nil, err
return nil, nil, err
}
certDER = block.Bytes
}
@ -861,7 +891,7 @@ func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
serialHex, strings.Join(csr.DNSNames, ", "), hex.EncodeToString(csr.Raw),
hex.EncodeToString(certDER))
return certDER, nil
return certDER, issuer, nil
}
func (ca *CertificateAuthorityImpl) storeCertificate(

View File

@ -267,15 +267,15 @@ func setup(t *testing.T) *testCtx {
Signer: caKey,
Clk: fc,
Profile: bsigner.ProfileConfig{
AllowECDSAKeys: true,
AllowRSAKeys: true,
AllowMustStaple: true,
AllowCTPoison: true,
AllowSCTList: true,
AllowCommonName: true,
IssuerURL: "http://not-example.com/issuer-url",
OCSPURL: "http://not-example.com/ocsp",
CRLURL: "http://not-example.com/crl",
UseForECDSALeaves: true,
UseForRSALeaves: true,
AllowMustStaple: true,
AllowCTPoison: true,
AllowSCTList: true,
AllowCommonName: true,
IssuerURL: "http://not-example.com/issuer-url",
OCSPURL: "http://not-example.com/ocsp",
CRLURL: "http://not-example.com/crl",
Policies: []bsigner.PolicyInformation{
{OID: "2.23.140.1.2.1"},
},
@ -1223,7 +1223,8 @@ func TestIssuePrecertificateLinting(t *testing.T) {
// Reconfigure the CA's cfsslSigner to be a linttrapSigner that always returns
// two LintResults.
ca.defaultIssuer.cfsslSigner = &linttrapSigner{
rsaIssuer := ca.issuers.byAlg[x509.RSA]
rsaIssuer.cfsslSigner = &linttrapSigner{
lintErr: &local.LintError{
ErrorResults: map[string]lint.LintResult{
"foobar": {
@ -1286,8 +1287,9 @@ func TestGenerateOCSPWithIssuerID(t *testing.T) {
test.AssertError(t, err, "GenerateOCSP didn't fail with invalid IssuerID")
// GenerateOCSP with feature enabled + req contains good IssuerID
rsaIssuer := ca.issuers.byAlg[x509.RSA]
_, err = ca.GenerateOCSP(context.Background(), &capb.GenerateOCSPRequest{
IssuerID: idForIssuer(ca.defaultIssuer.cert),
IssuerID: idForIssuer(rsaIssuer.cert),
Serial: "DEADDEADDEADDEADDEADDEADDEADDEADDEAD",
Status: string(core.OCSPStatusGood),
})

View File

@ -239,7 +239,6 @@ func TestRootConfigValidate(t *testing.T) {
SkipLints: []string{
"e_ext_authority_key_identifier_missing",
"e_ext_authority_key_identifier_no_key_identifier",
"e_sub_ca_aia_does_not_contain_ocsp_url",
"e_sub_ca_aia_missing",
"e_sub_ca_certificate_policies_missing",
"e_sub_ca_crl_distribution_points_missing",

View File

@ -46,8 +46,8 @@ type IssuanceRequest struct {
}
type signingProfile struct {
allowRSAKeys bool
allowECDSAKeys bool
useForRSALeaves bool
useForECDSALeaves bool
allowMustStaple bool
allowCTPoison bool
@ -78,8 +78,9 @@ type PolicyInformation struct {
// ProfileConfig describes the certificate issuance constraints
type ProfileConfig struct {
AllowRSAKeys bool
AllowECDSAKeys bool
UseForRSALeaves bool
UseForECDSALeaves bool
AllowMustStaple bool
AllowCTPoison bool
AllowSCTList bool
@ -114,17 +115,17 @@ var stringToQualifierType = map[string]asn1.ObjectIdentifier{
func newProfile(config ProfileConfig) (*signingProfile, error) {
sp := &signingProfile{
allowRSAKeys: config.AllowRSAKeys,
allowECDSAKeys: config.AllowECDSAKeys,
allowMustStaple: config.AllowMustStaple,
allowCTPoison: config.AllowCTPoison,
allowSCTList: config.AllowSCTList,
allowCommonName: config.AllowCommonName,
issuerURL: config.IssuerURL,
crlURL: config.CRLURL,
ocspURL: config.OCSPURL,
maxBackdate: config.MaxValidityBackdate.Duration,
maxValidity: config.MaxValidityPeriod.Duration,
useForRSALeaves: config.UseForRSALeaves,
useForECDSALeaves: config.UseForECDSALeaves,
allowMustStaple: config.AllowMustStaple,
allowCTPoison: config.AllowCTPoison,
allowSCTList: config.AllowSCTList,
allowCommonName: config.AllowCommonName,
issuerURL: config.IssuerURL,
crlURL: config.CRLURL,
ocspURL: config.OCSPURL,
maxBackdate: config.MaxValidityBackdate.Duration,
maxValidity: config.MaxValidityPeriod.Duration,
}
if config.IssuerURL == "" {
return nil, errors.New("Issuer URL is required")
@ -170,12 +171,12 @@ func newProfile(config ProfileConfig) (*signingProfile, error) {
func (p *signingProfile) requestValid(clk clock.Clock, req *IssuanceRequest) error {
switch req.PublicKey.(type) {
case *rsa.PublicKey:
if !p.allowRSAKeys {
return errors.New("RSA keys not allowed")
if !p.useForRSALeaves {
return errors.New("cannot sign RSA public keys")
}
case *ecdsa.PublicKey:
if !p.allowECDSAKeys {
return errors.New("ECDSA keys not allowed")
if !p.useForECDSALeaves {
return errors.New("cannot sign ECDSA public keys")
}
default:
return errors.New("unsupported public key type")

View File

@ -25,14 +25,14 @@ import (
func defaultProfileConfig() ProfileConfig {
return ProfileConfig{
AllowECDSAKeys: true,
AllowRSAKeys: true,
AllowCommonName: true,
AllowCTPoison: true,
AllowSCTList: true,
AllowMustStaple: true,
IssuerURL: "http://issuer-url",
OCSPURL: "http://ocsp-url",
UseForECDSALeaves: true,
UseForRSALeaves: true,
AllowCommonName: true,
AllowCTPoison: true,
AllowSCTList: true,
AllowMustStaple: true,
IssuerURL: "http://issuer-url",
OCSPURL: "http://ocsp-url",
Policies: []PolicyInformation{
{OID: "1.2.3"},
},
@ -55,14 +55,14 @@ func TestNewProfilePolicies(t *testing.T) {
profile, err := newProfile(config)
test.AssertNotError(t, err, "newProfile failed")
test.AssertDeepEquals(t, *profile, signingProfile{
allowRSAKeys: true,
allowECDSAKeys: true,
allowMustStaple: true,
allowCTPoison: true,
allowSCTList: true,
allowCommonName: true,
issuerURL: "http://issuer-url",
ocspURL: "http://ocsp-url",
useForRSALeaves: true,
useForECDSALeaves: true,
allowMustStaple: true,
allowCTPoison: true,
allowSCTList: true,
allowCommonName: true,
issuerURL: "http://issuer-url",
ocspURL: "http://ocsp-url",
policies: &pkix.Extension{
Id: asn1.ObjectIdentifier{2, 5, 29, 32},
Value: []byte{48, 36, 48, 4, 6, 2, 42, 3, 48, 28, 6, 3, 42, 3, 4, 48, 21, 48, 19, 6, 8, 43, 6, 1, 5, 5, 7, 2, 1, 22, 7, 99, 112, 115, 45, 117, 114, 108},
@ -142,21 +142,21 @@ func TestRequestValid(t *testing.T) {
expectedError: "unsupported public key type",
},
{
name: "rsa keys not allowed",
name: "cannot sign rsa",
profile: &signingProfile{},
request: &IssuanceRequest{PublicKey: &rsa.PublicKey{}},
expectedError: "RSA keys not allowed",
expectedError: "cannot sign RSA public keys",
},
{
name: "ecdsa keys not allowed",
name: "cannot sign ecdsa",
profile: &signingProfile{},
request: &IssuanceRequest{PublicKey: &ecdsa.PublicKey{}},
expectedError: "ECDSA keys not allowed",
expectedError: "cannot sign ECDSA public keys",
},
{
name: "must staple not allowed",
profile: &signingProfile{
allowECDSAKeys: true,
useForECDSALeaves: true,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -167,7 +167,7 @@ func TestRequestValid(t *testing.T) {
{
name: "ct poison not allowed",
profile: &signingProfile{
allowECDSAKeys: true,
useForECDSALeaves: true,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -178,7 +178,7 @@ func TestRequestValid(t *testing.T) {
{
name: "sct list not allowed",
profile: &signingProfile{
allowECDSAKeys: true,
useForECDSALeaves: true,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -189,9 +189,9 @@ func TestRequestValid(t *testing.T) {
{
name: "sct list and ct poison not allowed",
profile: &signingProfile{
allowECDSAKeys: true,
allowCTPoison: true,
allowSCTList: true,
useForECDSALeaves: true,
allowCTPoison: true,
allowSCTList: true,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -203,7 +203,7 @@ func TestRequestValid(t *testing.T) {
{
name: "common name not allowed",
profile: &signingProfile{
allowECDSAKeys: true,
useForECDSALeaves: true,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -214,7 +214,7 @@ func TestRequestValid(t *testing.T) {
{
name: "negative validity",
profile: &signingProfile{
allowECDSAKeys: true,
useForECDSALeaves: true,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -226,8 +226,8 @@ func TestRequestValid(t *testing.T) {
{
name: "validity larger than max",
profile: &signingProfile{
allowECDSAKeys: true,
maxValidity: time.Minute,
useForECDSALeaves: true,
maxValidity: time.Minute,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -239,9 +239,9 @@ func TestRequestValid(t *testing.T) {
{
name: "validity backdated more than max",
profile: &signingProfile{
allowECDSAKeys: true,
maxValidity: time.Hour * 2,
maxBackdate: time.Hour,
useForECDSALeaves: true,
maxValidity: time.Hour * 2,
maxBackdate: time.Hour,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -253,9 +253,9 @@ func TestRequestValid(t *testing.T) {
{
name: "validity is forward dated",
profile: &signingProfile{
allowECDSAKeys: true,
maxValidity: time.Hour * 2,
maxBackdate: time.Hour,
useForECDSALeaves: true,
maxValidity: time.Hour * 2,
maxBackdate: time.Hour,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -267,8 +267,8 @@ func TestRequestValid(t *testing.T) {
{
name: "serial too short",
profile: &signingProfile{
allowECDSAKeys: true,
maxValidity: time.Hour * 2,
useForECDSALeaves: true,
maxValidity: time.Hour * 2,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -280,8 +280,8 @@ func TestRequestValid(t *testing.T) {
{
name: "serial too long",
profile: &signingProfile{
allowECDSAKeys: true,
maxValidity: time.Hour * 2,
useForECDSALeaves: true,
maxValidity: time.Hour * 2,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
@ -294,8 +294,8 @@ func TestRequestValid(t *testing.T) {
{
name: "good",
profile: &signingProfile{
allowECDSAKeys: true,
maxValidity: time.Hour * 2,
useForECDSALeaves: true,
maxValidity: time.Hour * 2,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},

View File

@ -23,7 +23,6 @@ certificate-profile:
skip-lints:
- e_ext_authority_key_identifier_missing
- e_ext_authority_key_identifier_no_key_identifier
- e_sub_ca_aia_does_not_contain_ocsp_url
- e_sub_ca_aia_missing
- e_sub_ca_certificate_policies_missing
- e_sub_ca_crl_distribution_points_missing