CA: Verify digitalSignature and certSign key usages (#5091)

When the CA loads new issuers (both their certificates and their
private keys), it performs a variety of sanity checks, such as
ensuring that the profile's signature algorithm matches the key
type.

With this change, we also check that the issuer's certificate has
the appropriate key usage bits set:
`certSign`, if it is going to be issuing end-entity certs; and
`digitalSignature`, because it will be signing OCSP responses for
previously-issued certificates.

Fixes #5068
This commit is contained in:
Aaron Gable 2020-09-18 16:10:12 -07:00 committed by GitHub
parent 3bf6aa4aac
commit 7672d9bc99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 2 deletions

View File

@ -353,6 +353,17 @@ func NewIssuer(cert *x509.Certificate, signer crypto.Signer, profile *Profile, l
default:
return nil, errors.New("unsupported issuer key type")
}
if profile.useForRSALeaves || profile.useForECDSALeaves {
if cert.KeyUsage&x509.KeyUsageCertSign == 0 {
return nil, errors.New("end-entity signing cert does not have keyUsage certSign")
}
}
// TODO(#5086): Only do this check for ocsp-issuing issuers.
if cert.KeyUsage&x509.KeyUsageDigitalSignature == 0 {
return nil, errors.New("end-entity ocsp signing cert does not have keyUsage digitalSignature")
}
i := &Issuer{
Cert: cert,
Signer: signer,

View File

@ -67,7 +67,7 @@ func TestMain(m *testing.M) {
Subject: pkix.Name{
CommonName: "big ca",
},
KeyUsage: x509.KeyUsageCertSign,
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature,
SubjectKeyId: []byte{1, 2, 3, 4, 5, 6, 7, 8},
}
issuer, err := x509.CreateCertificate(rand.Reader, template, template, tk.Public(), tk)
@ -409,7 +409,18 @@ func TestGenerateTemplate(t *testing.T) {
}
}
func TestNewSignerUnsupportedKeyType(t *testing.T) {
func TestNewIssuer(t *testing.T) {
_, err := NewIssuer(
issuerCert,
issuerSigner,
defaultProfile(),
&lint.Linter{},
clock.NewFake(),
)
test.AssertNotError(t, err, "NewIssuer failed")
}
func TestNewIssuerUnsupportedKeyType(t *testing.T) {
_, err := NewIssuer(
&x509.Certificate{
PublicKey: &ed25519.PublicKey{},
@ -423,6 +434,59 @@ func TestNewSignerUnsupportedKeyType(t *testing.T) {
test.AssertEquals(t, err.Error(), "unsupported issuer key type")
}
func TestNewIssuerNoCertSign(t *testing.T) {
_, err := NewIssuer(
&x509.Certificate{
PublicKey: &ecdsa.PublicKey{
Curve: elliptic.P256(),
},
KeyUsage: 0,
},
issuerSigner,
defaultProfile(),
&lint.Linter{},
clock.NewFake(),
)
test.AssertError(t, err, "NewIssuer didn't fail")
test.AssertEquals(t, err.Error(), "end-entity signing cert does not have keyUsage certSign")
}
func TestNewIssuerNoDigitalSignature(t *testing.T) {
_, err := NewIssuer(
&x509.Certificate{
PublicKey: &ecdsa.PublicKey{
Curve: elliptic.P256(),
},
KeyUsage: x509.KeyUsageCertSign,
},
issuerSigner,
defaultProfile(),
&lint.Linter{},
clock.NewFake(),
)
test.AssertError(t, err, "NewIssuer didn't fail")
test.AssertEquals(t, err.Error(), "end-entity ocsp signing cert does not have keyUsage digitalSignature")
}
func TestNewIssuerOCSPOnly(t *testing.T) {
p := defaultProfile()
p.useForRSALeaves = false
p.useForECDSALeaves = false
_, err := NewIssuer(
&x509.Certificate{
PublicKey: &ecdsa.PublicKey{
Curve: elliptic.P256(),
},
KeyUsage: x509.KeyUsageDigitalSignature,
},
issuerSigner,
p,
&lint.Linter{},
clock.NewFake(),
)
test.AssertNotError(t, err, "NewIssuer failed")
}
func TestIssue(t *testing.T) {
for _, tc := range []struct {
name string