Clean up must staple and precert options in CA (#4201)
Precertificate issuance has been the only supported mode for a while now. This cleans up the remaining flags in the CA code. The same is true of must staple. This also removes the IssueCertificate RPC call and its corresponding wrappers, and removes a lot of plumbing in the CA unittests that was used to test the situation where precertificate issuance was not enabled.
This commit is contained in:
parent
ecc111c34d
commit
76beffe074
42
ca/ca.go
42
ca/ca.go
|
@ -128,7 +128,6 @@ type CertificateAuthorityImpl struct {
|
|||
backdate time.Duration
|
||||
maxNames int
|
||||
forceCNFromSAN bool
|
||||
enableMustStaple bool
|
||||
signatureCount *prometheus.CounterVec
|
||||
csrExtensionCount *prometheus.CounterVec
|
||||
orphanQueue *goque.Queue
|
||||
|
@ -273,7 +272,6 @@ func NewCertificateAuthorityImpl(
|
|||
stats: stats,
|
||||
keyPolicy: keyPolicy,
|
||||
forceCNFromSAN: !config.DoNotForceCN, // Note the inversion here
|
||||
enableMustStaple: config.EnableMustStaple,
|
||||
signatureCount: signatureCount,
|
||||
csrExtensionCount: csrExtensionCount,
|
||||
orphanQueue: orphanQueue,
|
||||
|
@ -351,9 +349,7 @@ func (ca *CertificateAuthorityImpl) extensionsFromCSR(csr *x509.CertificateReque
|
|||
return nil, berrors.MalformedError("unsupported value for extension with OID %v", ext.Type)
|
||||
}
|
||||
|
||||
if ca.enableMustStaple {
|
||||
extensions = append(extensions, mustStapleExtension)
|
||||
}
|
||||
extensions = append(extensions, mustStapleExtension)
|
||||
case ext.Type.Equal(oidAuthorityInfoAccess),
|
||||
ext.Type.Equal(oidAuthorityKeyIdentifier),
|
||||
ext.Type.Equal(oidBasicConstraints),
|
||||
|
@ -418,45 +414,13 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, xferObj co
|
|||
return ocspResponse, err
|
||||
}
|
||||
|
||||
// IssueCertificate attempts to convert a CSR into a signed Certificate, while
|
||||
// enforcing all policies. Names (domains) in the CertificateRequest will be
|
||||
// lowercased before storage.
|
||||
// Currently it will always sign with the defaultIssuer.
|
||||
func (ca *CertificateAuthorityImpl) IssueCertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest) (core.Certificate, error) {
|
||||
emptyCert := core.Certificate{}
|
||||
|
||||
if issueReq.RegistrationID == nil {
|
||||
return emptyCert, berrors.InternalServerError("RegistrationID is nil")
|
||||
}
|
||||
|
||||
// OrderID is an optional field only used by the "ACME v2" issuance flow. If
|
||||
// it isn't nil, then populate the `orderID` var with the request's OrderID.
|
||||
// If it is nil, use the default int64 value of 0.
|
||||
var orderID int64
|
||||
if issueReq.OrderID != nil {
|
||||
orderID = *issueReq.OrderID
|
||||
}
|
||||
|
||||
serialBigInt, validity, err := ca.generateSerialNumberAndValidity()
|
||||
if err != nil {
|
||||
return emptyCert, err
|
||||
}
|
||||
|
||||
certDER, err := ca.issueCertificateOrPrecertificate(ctx, issueReq, serialBigInt, validity, certType)
|
||||
if err != nil {
|
||||
return emptyCert, err
|
||||
}
|
||||
|
||||
return ca.generateOCSPAndStoreCertificate(ctx, *issueReq.RegistrationID, orderID, serialBigInt, certDER)
|
||||
}
|
||||
|
||||
func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest) (*caPB.IssuePrecertificateResponse, error) {
|
||||
serialBigInt, validity, err := ca.generateSerialNumberAndValidity()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
precertDER, err := ca.issueCertificateOrPrecertificate(ctx, issueReq, serialBigInt, validity, precertType)
|
||||
precertDER, err := ca.issuePrecertificateInner(ctx, issueReq, serialBigInt, validity, precertType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -531,7 +495,7 @@ func (ca *CertificateAuthorityImpl) generateSerialNumberAndValidity() (*big.Int,
|
|||
return serialBigInt, validity, nil
|
||||
}
|
||||
|
||||
func (ca *CertificateAuthorityImpl) issueCertificateOrPrecertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest, serialBigInt *big.Int, validity validity, certType certificateType) ([]byte, error) {
|
||||
func (ca *CertificateAuthorityImpl) issuePrecertificateInner(ctx context.Context, issueReq *caPB.IssueCertificateRequest, serialBigInt *big.Int, validity validity, certType certificateType) ([]byte, error) {
|
||||
csr, err := x509.ParseCertificateRequest(issueReq.Csr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
172
ca/ca_test.go
172
ca/ca_test.go
|
@ -1,7 +1,6 @@
|
|||
package ca
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
|
@ -136,8 +135,8 @@ var (
|
|||
// |TestIssueCertificate| quite a bit, and since it isn't clear that that
|
||||
// would be useful, we've avoided adding that case, at least for now.
|
||||
issuanceModes = []IssuanceMode{
|
||||
{name: "precertificate", issuePrecertificate: true, issueCertificateForPrecertificate: false},
|
||||
{name: "certificate-for-precertificate", issuePrecertificate: false, issueCertificateForPrecertificate: true},
|
||||
{name: "precertificate", issueCertificateForPrecertificate: false},
|
||||
{name: "certificate-for-precertificate", issueCertificateForPrecertificate: true},
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -318,28 +317,25 @@ type TestCertificateIssuance struct {
|
|||
|
||||
type IssuanceMode struct {
|
||||
name string
|
||||
issuePrecertificate bool
|
||||
issueCertificateForPrecertificate bool
|
||||
}
|
||||
|
||||
func TestIssueCertificate(t *testing.T) {
|
||||
func TestIssuePrecertificate(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
csr []byte
|
||||
setup func(t *testing.T) (*CertificateAuthorityImpl, *mockSA)
|
||||
subTest func(t *testing.T, i *TestCertificateIssuance)
|
||||
}{
|
||||
{"IssueCertificate", CNandSANCSR, issueCertificateSubTestDefaultSetup, issueCertificateSubTestIssueCertificate},
|
||||
{"ValidityUsesCAClock", CNandSANCSR, issueCertificateSubTestDefaultSetup, issueCertificateSubTestValidityUsesCAClock},
|
||||
{"AllowNoCN", NoCNCSR, issueCertificateSubTestDefaultSetup, issueCertificateSubTestAllowNoCN},
|
||||
{"ProfileSelectionRSA", CNandSANCSR, issueCertificateSubTestDefaultSetup, issueCertificateSubTestProfileSelectionRSA},
|
||||
{"ProfileSelectionECDSA", ECDSACSR, issueCertificateSubTestDefaultSetup, issueCertificateSubTestProfileSelectionECDSA},
|
||||
{"MustStapleWhenDisabled", MustStapleCSR, issueCertificateSubTestMustStapleDisabledSetup, issueCertificateSubTestMustStapleWhenDisabled},
|
||||
{"MustStapleWhenEnabled", MustStapleCSR, issueCertificateSubTestMustStapleEnabledSetup, issueCertificateSubTestMustStapleWhenEnabled},
|
||||
{"MustStapleDuplicate", DuplicateMustStapleCSR, issueCertificateSubTestMustStapleEnabledSetup, issueCertificateSubTestMustStapleWhenEnabled},
|
||||
{"UnknownExtension", UnsupportedExtensionCSR, issueCertificateSubTestMustStapleEnabledSetup, issueCertificateSubTestUnknownExtension},
|
||||
{"CTPoisonExtension", CTPoisonExtensionCSR, issueCertificateSubTestDefaultSetup, issueCertificateSubTestCTPoisonExtension},
|
||||
{"CTPoisonExtensionEmpty", CTPoisonExtensionEmptyCSR, issueCertificateSubTestDefaultSetup, issueCertificateSubTestCTPoisonExtension},
|
||||
{"IssuePrecertificate", CNandSANCSR, issueCertificateSubTestIssuePrecertificate},
|
||||
{"ValidityUsesCAClock", CNandSANCSR, issueCertificateSubTestValidityUsesCAClock},
|
||||
{"AllowNoCN", NoCNCSR, issueCertificateSubTestAllowNoCN},
|
||||
{"ProfileSelectionRSA", CNandSANCSR, issueCertificateSubTestProfileSelectionRSA},
|
||||
{"ProfileSelectionECDSA", ECDSACSR, issueCertificateSubTestProfileSelectionECDSA},
|
||||
{"MustStaple", MustStapleCSR, issueCertificateSubTestMustStaple},
|
||||
{"MustStapleDuplicate", DuplicateMustStapleCSR, issueCertificateSubTestMustStaple},
|
||||
{"UnknownExtension", UnsupportedExtensionCSR, issueCertificateSubTestUnknownExtension},
|
||||
{"CTPoisonExtension", CTPoisonExtensionCSR, issueCertificateSubTestCTPoisonExtension},
|
||||
{"CTPoisonExtensionEmpty", CTPoisonExtensionEmptyCSR, issueCertificateSubTestCTPoisonExtension},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
|
@ -348,7 +344,7 @@ func TestIssueCertificate(t *testing.T) {
|
|||
// the precertificates previously generated from the preceding
|
||||
// "precertificate" test. See also the comment above |issuanceModes|.
|
||||
for _, mode := range issuanceModes {
|
||||
ca, sa := testCase.setup(t)
|
||||
ca, sa := issueCertificateSubTestSetup(t)
|
||||
|
||||
t.Run(mode.name+"-"+testCase.name, func(t *testing.T) {
|
||||
req, err := x509.ParseCertificateRequest(testCase.csr)
|
||||
|
@ -357,25 +353,16 @@ func TestIssueCertificate(t *testing.T) {
|
|||
issueReq := &caPB.IssueCertificateRequest{Csr: testCase.csr, RegistrationID: &arbitraryRegID}
|
||||
|
||||
var certDER []byte
|
||||
if mode.issuePrecertificate {
|
||||
response, err := ca.IssuePrecertificate(ctx, issueReq)
|
||||
response, err := ca.IssuePrecertificate(ctx, issueReq)
|
||||
|
||||
test.AssertNotError(t, err, "Failed to issue precertificate")
|
||||
certDER = response.DER
|
||||
} else {
|
||||
coreCert, err := ca.IssueCertificate(ctx, issueReq)
|
||||
test.AssertNotError(t, err, "Failed to issue certificate")
|
||||
certDER = coreCert.DER
|
||||
|
||||
// Verify that the cert got stored in the DB
|
||||
test.Assert(t, bytes.Equal(certDER, sa.certificate.DER), "Retrieved cert not equal to issued cert.")
|
||||
}
|
||||
test.AssertNotError(t, err, "Failed to issue precertificate")
|
||||
certDER = response.DER
|
||||
|
||||
cert, err := x509.ParseCertificate(certDER)
|
||||
test.AssertNotError(t, err, "Certificate failed to parse")
|
||||
|
||||
poisonExtension := findExtension(cert.Extensions, OIDExtensionCTPoison)
|
||||
test.AssertEquals(t, mode.issuePrecertificate, poisonExtension != nil)
|
||||
test.AssertEquals(t, true, poisonExtension != nil)
|
||||
if poisonExtension != nil {
|
||||
test.AssertEquals(t, poisonExtension.Critical, true)
|
||||
test.AssertDeepEquals(t, poisonExtension.Value, []byte{0x05, 0x00}) // ASN.1 DER NULL
|
||||
|
@ -396,7 +383,7 @@ func TestIssueCertificate(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func issueCertificateSubTestDefaultSetup(t *testing.T) (*CertificateAuthorityImpl, *mockSA) {
|
||||
func issueCertificateSubTestSetup(t *testing.T) (*CertificateAuthorityImpl, *mockSA) {
|
||||
testCtx := setup(t)
|
||||
sa := &mockSA{}
|
||||
ca, err := NewCertificateAuthorityImpl(
|
||||
|
@ -415,7 +402,7 @@ func issueCertificateSubTestDefaultSetup(t *testing.T) (*CertificateAuthorityImp
|
|||
return ca, sa
|
||||
}
|
||||
|
||||
func issueCertificateSubTestIssueCertificate(t *testing.T, i *TestCertificateIssuance) {
|
||||
func issueCertificateSubTestIssuePrecertificate(t *testing.T, i *TestCertificateIssuance) {
|
||||
cert := i.cert
|
||||
|
||||
test.AssertEquals(t, cert.Subject.CommonName, "not-example.com")
|
||||
|
@ -472,7 +459,7 @@ func TestMultipleIssuers(t *testing.T) {
|
|||
nil)
|
||||
test.AssertNotError(t, err, "Failed to remake CA")
|
||||
|
||||
issuedCert, err := ca.IssueCertificate(ctx, &caPB.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: &arbitraryRegID})
|
||||
issuedCert, err := ca.IssuePrecertificate(ctx, &caPB.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: &arbitraryRegID})
|
||||
test.AssertNotError(t, err, "Failed to issue certificate")
|
||||
|
||||
cert, err := x509.ParseCertificate(issuedCert.DER)
|
||||
|
@ -499,7 +486,7 @@ func TestOCSP(t *testing.T) {
|
|||
|
||||
issueReq := caPB.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: &arbitraryRegID}
|
||||
|
||||
cert, err := ca.IssueCertificate(ctx, &issueReq)
|
||||
cert, err := ca.IssuePrecertificate(ctx, &issueReq)
|
||||
test.AssertNotError(t, err, "Failed to issue")
|
||||
parsedCert, err := x509.ParseCertificate(cert.DER)
|
||||
test.AssertNotError(t, err, "Failed to parse cert")
|
||||
|
@ -547,8 +534,8 @@ func TestOCSP(t *testing.T) {
|
|||
nil)
|
||||
test.AssertNotError(t, err, "Failed to remake CA")
|
||||
|
||||
// Now issue a new cert, signed by newIssuerCert
|
||||
newCert, err := ca.IssueCertificate(ctx, &issueReq)
|
||||
// Now issue a new precert, signed by newIssuerCert
|
||||
newCert, err := ca.IssuePrecertificate(ctx, &issueReq)
|
||||
test.AssertNotError(t, err, "Failed to issue newCert")
|
||||
parsedNewCert, err := x509.ParseCertificate(newCert.DER)
|
||||
test.AssertNotError(t, err, "Failed to parse newCert")
|
||||
|
@ -629,39 +616,33 @@ func TestInvalidCSRs(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
for _, mode := range issuanceModes {
|
||||
testCtx := setup(t)
|
||||
sa := &mockSA{}
|
||||
ca, err := NewCertificateAuthorityImpl(
|
||||
testCtx.caConfig,
|
||||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.fc,
|
||||
testCtx.stats,
|
||||
testCtx.issuers,
|
||||
testCtx.keyPolicy,
|
||||
testCtx.logger,
|
||||
nil)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
testCtx := setup(t)
|
||||
sa := &mockSA{}
|
||||
ca, err := NewCertificateAuthorityImpl(
|
||||
testCtx.caConfig,
|
||||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.fc,
|
||||
testCtx.stats,
|
||||
testCtx.issuers,
|
||||
testCtx.keyPolicy,
|
||||
testCtx.logger,
|
||||
nil)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
|
||||
t.Run(mode.name+"-"+testCase.name, func(t *testing.T) {
|
||||
serializedCSR := mustRead(testCase.csrPath)
|
||||
issueReq := &caPB.IssueCertificateRequest{Csr: serializedCSR, RegistrationID: &arbitraryRegID}
|
||||
if !mode.issuePrecertificate {
|
||||
_, err = ca.IssueCertificate(ctx, issueReq)
|
||||
} else {
|
||||
_, err = ca.IssuePrecertificate(ctx, issueReq)
|
||||
}
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
serializedCSR := mustRead(testCase.csrPath)
|
||||
issueReq := &caPB.IssueCertificateRequest{Csr: serializedCSR, RegistrationID: &arbitraryRegID}
|
||||
_, err = ca.IssuePrecertificate(ctx, issueReq)
|
||||
|
||||
test.Assert(t, berrors.Is(err, berrors.Malformed), "Incorrect error type returned")
|
||||
test.AssertEquals(t, signatureCountByPurpose("cert", ca.signatureCount), 0)
|
||||
test.Assert(t, berrors.Is(err, berrors.Malformed), "Incorrect error type returned")
|
||||
test.AssertEquals(t, signatureCountByPurpose("cert", ca.signatureCount), 0)
|
||||
|
||||
test.AssertError(t, err, testCase.errorMessage)
|
||||
if testCase.check != nil {
|
||||
testCase.check(t, ca, sa)
|
||||
}
|
||||
})
|
||||
}
|
||||
test.AssertError(t, err, testCase.errorMessage)
|
||||
if testCase.check != nil {
|
||||
testCase.check(t, ca, sa)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -686,7 +667,7 @@ func TestRejectValidityTooLong(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Failed to parse time")
|
||||
testCtx.fc.Set(future)
|
||||
// Test that the CA rejects CSRs that would expire after the intermediate cert
|
||||
_, err = ca.IssueCertificate(ctx, &caPB.IssueCertificateRequest{Csr: NoCNCSR, RegistrationID: &arbitraryRegID})
|
||||
_, err = ca.IssuePrecertificate(ctx, &caPB.IssueCertificateRequest{Csr: NoCNCSR, RegistrationID: &arbitraryRegID})
|
||||
test.AssertError(t, err, "Cannot issue a certificate that expires after the intermediate certificate")
|
||||
test.Assert(t, berrors.Is(err, berrors.InternalServer), "Incorrect error type returned")
|
||||
}
|
||||
|
@ -776,18 +757,6 @@ func issueCertificateSubTestProfileSelectionECDSA(t *testing.T, i *TestCertifica
|
|||
test.AssertEquals(t, i.cert.KeyUsage, expectedKeyUsage)
|
||||
}
|
||||
|
||||
func issueCertificateSubTestMustStapleDisabledSetup(t *testing.T) (*CertificateAuthorityImpl, *mockSA) {
|
||||
ca, sa := issueCertificateSubTestDefaultSetup(t)
|
||||
ca.enableMustStaple = false
|
||||
return ca, sa
|
||||
}
|
||||
|
||||
func issueCertificateSubTestMustStapleEnabledSetup(t *testing.T) (*CertificateAuthorityImpl, *mockSA) {
|
||||
ca, sa := issueCertificateSubTestDefaultSetup(t)
|
||||
ca.enableMustStaple = true
|
||||
return ca, sa
|
||||
}
|
||||
|
||||
func countMustStaple(t *testing.T, cert *x509.Certificate) (count int) {
|
||||
oidTLSFeature := asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 24}
|
||||
for _, ext := range cert.Extensions {
|
||||
|
@ -800,30 +769,12 @@ func countMustStaple(t *testing.T, cert *x509.Certificate) (count int) {
|
|||
return count
|
||||
}
|
||||
|
||||
func issueCertificateSubTestMustStapleWhenDisabled(t *testing.T, i *TestCertificateIssuance) {
|
||||
// With ca.enableMustStaple = false, should issue successfully and not add
|
||||
// Must Staple.
|
||||
certType := "certificate"
|
||||
if i.mode.issuePrecertificate {
|
||||
certType = "precertificate"
|
||||
}
|
||||
func issueCertificateSubTestMustStaple(t *testing.T, i *TestCertificateIssuance) {
|
||||
// a TLS feature extension should put a must-staple extension into the cert. Even
|
||||
// if there are multiple TLS Feature extensions, only one extension should be included.
|
||||
test.AssertEquals(t, test.CountCounterVec(csrExtensionCategory, csrExtensionTLSFeature, i.ca.csrExtensionCount), 1)
|
||||
test.AssertEquals(t, test.CountCounterVec(csrExtensionCategory, csrExtensionTLSFeatureInvalid, i.ca.csrExtensionCount), 0)
|
||||
test.AssertEquals(t, signatureCountByPurpose(certType, i.ca.signatureCount), 1)
|
||||
test.AssertEquals(t, countMustStaple(t, i.cert), 0)
|
||||
}
|
||||
|
||||
func issueCertificateSubTestMustStapleWhenEnabled(t *testing.T, i *TestCertificateIssuance) {
|
||||
// With ca.enableMustStaple = true, a TLS feature extension should put a must-staple
|
||||
// extension into the cert. Even if there are multiple TLS Feature extensions, only
|
||||
// one extension should be included.
|
||||
certType := "certificate"
|
||||
if i.mode.issuePrecertificate {
|
||||
certType = "precertificate"
|
||||
}
|
||||
test.AssertEquals(t, test.CountCounterVec(csrExtensionCategory, csrExtensionTLSFeature, i.ca.csrExtensionCount), 1)
|
||||
test.AssertEquals(t, test.CountCounterVec(csrExtensionCategory, csrExtensionTLSFeatureInvalid, i.ca.csrExtensionCount), 0)
|
||||
test.AssertEquals(t, signatureCountByPurpose(certType, i.ca.signatureCount), 1)
|
||||
test.AssertEquals(t, signatureCountByPurpose("precertificate", i.ca.signatureCount), 1)
|
||||
test.AssertEquals(t, countMustStaple(t, i.cert), 1)
|
||||
}
|
||||
|
||||
|
@ -834,19 +785,12 @@ func issueCertificateSubTestTLSFeatureUnknown(t *testing.T, ca *CertificateAutho
|
|||
|
||||
func issueCertificateSubTestUnknownExtension(t *testing.T, i *TestCertificateIssuance) {
|
||||
// Unsupported extensions in the CSR should be silently ignored.
|
||||
certType := "certificate"
|
||||
if i.mode.issuePrecertificate {
|
||||
certType = "precertificate"
|
||||
}
|
||||
test.AssertEquals(t, test.CountCounterVec(csrExtensionCategory, csrExtensionOther, i.ca.csrExtensionCount), 1)
|
||||
test.AssertEquals(t, signatureCountByPurpose(certType, i.ca.signatureCount), 1)
|
||||
test.AssertEquals(t, signatureCountByPurpose("precertificate", i.ca.signatureCount), 1)
|
||||
|
||||
// NOTE: The hard-coded value here will have to change over time as Boulder
|
||||
// adds new (unrequested) extensions to certificates.
|
||||
expectedExtensionCount := 9
|
||||
if i.mode.issuePrecertificate {
|
||||
expectedExtensionCount += 1
|
||||
}
|
||||
expectedExtensionCount := 10
|
||||
test.AssertEquals(t, len(i.cert.Extensions), expectedExtensionCount)
|
||||
}
|
||||
|
||||
|
@ -855,12 +799,8 @@ func issueCertificateSubTestCTPoisonExtension(t *testing.T, i *TestCertificateIs
|
|||
// unknown extension, whether it has a valid or invalid value. The check
|
||||
// for whether or not the poison extension is present in the issued
|
||||
// certificate/precertificate is done in the caller.
|
||||
certType := "certificate"
|
||||
if i.mode.issuePrecertificate {
|
||||
certType = "precertificate"
|
||||
}
|
||||
test.AssertEquals(t, test.CountCounterVec(csrExtensionCategory, csrExtensionOther, i.ca.csrExtensionCount), 1)
|
||||
test.AssertEquals(t, signatureCountByPurpose(certType, i.ca.signatureCount), 1)
|
||||
test.AssertEquals(t, signatureCountByPurpose("precertificate", i.ca.signatureCount), 1)
|
||||
}
|
||||
|
||||
func findExtension(extensions []pkix.Extension, id asn1.ObjectIdentifier) *pkix.Extension {
|
||||
|
|
|
@ -20,10 +20,7 @@ type CAConfig struct {
|
|||
|
||||
RSAProfile string
|
||||
ECDSAProfile string
|
||||
TestMode bool
|
||||
SerialPrefix int
|
||||
// TODO(jsha): Remove Key field once we've migrated to Issuers
|
||||
Key *IssuerConfig
|
||||
// Issuers contains configuration information for each issuer cert and key
|
||||
// this CA knows about. The first in the list is used as the default.
|
||||
Issuers []IssuerConfig
|
||||
|
@ -45,14 +42,6 @@ type CAConfig struct {
|
|||
// not pull a SAN entry to be the CN if no CN was given in a CSR.
|
||||
DoNotForceCN bool
|
||||
|
||||
// EnableMustStaple governs whether the Must Staple extension in CSRs
|
||||
// triggers issuance of certificates with Must Staple.
|
||||
EnableMustStaple bool
|
||||
|
||||
// EnablePrecertificateFlow governs whether precertificate-based issuance
|
||||
// is enabled.
|
||||
EnablePrecertificateFlow bool
|
||||
|
||||
// WeakKeyFile is the path to a JSON file containing truncated RSA modulus
|
||||
// hashes of known easily enumerable keys.
|
||||
WeakKeyFile string
|
||||
|
|
|
@ -297,33 +297,32 @@ func init() {
|
|||
func init() { proto.RegisterFile("ca/proto/ca.proto", fileDescriptor_8f9fdc2529716820) }
|
||||
|
||||
var fileDescriptor_8f9fdc2529716820 = []byte{
|
||||
// 401 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0x41, 0xab, 0xd3, 0x40,
|
||||
0x10, 0x6e, 0x92, 0xf7, 0xac, 0x6f, 0x88, 0xd2, 0xb7, 0x4f, 0x7d, 0x21, 0x15, 0xac, 0x39, 0x48,
|
||||
0x10, 0x49, 0xa1, 0x57, 0x4f, 0xb5, 0xa9, 0x52, 0x10, 0x2c, 0x5b, 0xbd, 0x78, 0x5b, 0xb6, 0x53,
|
||||
0x0d, 0x62, 0xb6, 0xce, 0x6e, 0x04, 0x0f, 0xfe, 0x09, 0x7f, 0x9d, 0x3f, 0x47, 0xb2, 0x4d, 0xda,
|
||||
0x34, 0xa4, 0xf6, 0xf0, 0x6e, 0x33, 0xf3, 0x65, 0xe7, 0xfb, 0xe6, 0x9b, 0x09, 0x5c, 0x4b, 0x31,
|
||||
0xde, 0x92, 0x32, 0x6a, 0x2c, 0x45, 0x62, 0x03, 0xe6, 0x4a, 0x11, 0x3e, 0x96, 0x8a, 0xb0, 0x06,
|
||||
0x14, 0xe1, 0x0e, 0x8a, 0xbe, 0xc3, 0xed, 0x42, 0xeb, 0x02, 0x67, 0x48, 0x26, 0xdb, 0x64, 0x52,
|
||||
0x18, 0xe4, 0xf8, 0xa3, 0x40, 0x6d, 0xd8, 0x00, 0x3c, 0xa9, 0x29, 0x70, 0x46, 0x4e, 0xec, 0xf3,
|
||||
0x32, 0x64, 0x2f, 0xe0, 0x21, 0xe1, 0x97, 0x4c, 0x1b, 0x12, 0x26, 0x53, 0xf9, 0x22, 0x0d, 0xdc,
|
||||
0x91, 0x13, 0x7b, 0xbc, 0x55, 0x65, 0x01, 0xf4, 0x15, 0xad, 0x91, 0x16, 0x69, 0xe0, 0xd9, 0x0f,
|
||||
0xea, 0x34, 0x1a, 0xc3, 0xd0, 0xd2, 0x2d, 0x09, 0x65, 0x93, 0x51, 0x6f, 0x55, 0xae, 0xb1, 0xa4,
|
||||
0x4c, 0xe7, 0xbc, 0xa6, 0x4c, 0xe7, 0x3c, 0xfa, 0xe3, 0x40, 0xdc, 0x16, 0xf8, 0x56, 0x51, 0xfb,
|
||||
0xfd, 0x5e, 0xf1, 0xf1, 0x73, 0xc6, 0xe0, 0x62, 0x35, 0xfb, 0xa8, 0x03, 0x77, 0xe4, 0xc5, 0x3e,
|
||||
0xb7, 0x71, 0xc7, 0x14, 0xde, 0xb9, 0x29, 0x2e, 0x8e, 0xa7, 0xf8, 0x0d, 0x37, 0xef, 0x30, 0x47,
|
||||
0x12, 0x06, 0x3f, 0xcc, 0x56, 0xcb, 0x9a, 0x3e, 0x80, 0x7e, 0x29, 0xea, 0x20, 0xa1, 0x4e, 0xd9,
|
||||
0x13, 0xb8, 0xa7, 0x8d, 0x30, 0x85, 0xb6, 0x86, 0x5d, 0xf1, 0x2a, 0x2b, 0xeb, 0x84, 0x42, 0xab,
|
||||
0xdc, 0x4a, 0xb8, 0xe4, 0x55, 0xc6, 0x9e, 0xc2, 0x15, 0xe1, 0x4f, 0xf5, 0x0d, 0xd7, 0x53, 0x53,
|
||||
0x91, 0x1f, 0x0a, 0xd1, 0x4b, 0xf0, 0x77, 0xb4, 0x95, 0x6b, 0x21, 0xdc, 0xa7, 0x2a, 0xae, 0x88,
|
||||
0xf7, 0xf9, 0xe4, 0xaf, 0x0b, 0x8f, 0x1a, 0xd6, 0x4d, 0x0b, 0xf3, 0x55, 0x51, 0x66, 0x7e, 0xb1,
|
||||
0x14, 0x06, 0x6d, 0x5f, 0xd9, 0x30, 0x91, 0x22, 0x39, 0x71, 0x0e, 0xe1, 0x75, 0x62, 0xcf, 0xa6,
|
||||
0x81, 0x44, 0x3d, 0xf6, 0x09, 0x6e, 0x3a, 0xf6, 0xf9, 0xff, 0x46, 0xcf, 0xf6, 0x60, 0xf7, 0x15,
|
||||
0x44, 0x3d, 0xb6, 0x81, 0xe7, 0x67, 0x97, 0xce, 0x5e, 0x75, 0x91, 0x9c, 0xba, 0x8d, 0x6e, 0xf9,
|
||||
0xaf, 0xc1, 0x6f, 0x2e, 0x92, 0xdd, 0x96, 0x2d, 0x3b, 0x56, 0x1b, 0x0e, 0x4a, 0xa0, 0x69, 0x7a,
|
||||
0xd4, 0x9b, 0xbc, 0x87, 0x07, 0x65, 0xa5, 0xfa, 0x5c, 0xd1, 0x9d, 0xba, 0xbd, 0xe9, 0x7f, 0xbe,
|
||||
0xb4, 0x7f, 0xe4, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x16, 0x23, 0x09, 0x70, 0xc0, 0x03, 0x00,
|
||||
0x00,
|
||||
// 389 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0x41, 0xaf, 0xd2, 0x40,
|
||||
0x10, 0xa6, 0xed, 0x7b, 0xe2, 0x9b, 0x54, 0xf3, 0x58, 0x54, 0x9a, 0x62, 0x22, 0xf6, 0x60, 0x1a,
|
||||
0x63, 0x4a, 0xc2, 0xd5, 0x13, 0x52, 0x34, 0x24, 0x26, 0x92, 0x45, 0x2f, 0xde, 0x36, 0xcb, 0xa0,
|
||||
0x8d, 0xb1, 0x8b, 0xb3, 0x5b, 0x13, 0x0f, 0xfe, 0x09, 0x7e, 0xb1, 0xe9, 0xd2, 0x42, 0x21, 0x25,
|
||||
0x1c, 0xbc, 0xcd, 0x37, 0x33, 0xbb, 0xdf, 0x37, 0xf3, 0xed, 0x42, 0x4f, 0x8a, 0xf1, 0x96, 0x94,
|
||||
0x51, 0x63, 0x29, 0x12, 0x1b, 0x30, 0x57, 0x8a, 0xf0, 0xa9, 0x54, 0x84, 0x75, 0x41, 0x11, 0xee,
|
||||
0x4b, 0xd1, 0x4f, 0x18, 0x2c, 0xb4, 0x2e, 0x70, 0x86, 0x64, 0xb2, 0x4d, 0x26, 0x85, 0x41, 0x8e,
|
||||
0xbf, 0x0a, 0xd4, 0x86, 0xdd, 0x83, 0x27, 0x35, 0x05, 0xce, 0xc8, 0x89, 0x7d, 0x5e, 0x86, 0xec,
|
||||
0x15, 0x3c, 0x26, 0xfc, 0x96, 0x69, 0x43, 0xc2, 0x64, 0x2a, 0x5f, 0xa4, 0x81, 0x3b, 0x72, 0x62,
|
||||
0x8f, 0x9f, 0x65, 0x59, 0x00, 0x5d, 0x45, 0x6b, 0xa4, 0x45, 0x1a, 0x78, 0xb6, 0xa1, 0x86, 0xd1,
|
||||
0x18, 0x86, 0x96, 0x6e, 0x49, 0x28, 0x9b, 0x8c, 0x7a, 0xab, 0x72, 0x8d, 0x25, 0x65, 0x3a, 0xe7,
|
||||
0x35, 0x65, 0x3a, 0xe7, 0xd1, 0xce, 0x81, 0xf8, 0x5c, 0xe0, 0x7b, 0x45, 0xe7, 0xe7, 0x0f, 0x8a,
|
||||
0x4f, 0x8f, 0x33, 0x06, 0x37, 0xab, 0xd9, 0x67, 0x1d, 0xb8, 0x23, 0x2f, 0xf6, 0xb9, 0x8d, 0x5b,
|
||||
0xa6, 0xf0, 0xae, 0x4d, 0x71, 0x73, 0x3a, 0xc5, 0x5f, 0xe8, 0x7f, 0xc0, 0x1c, 0x49, 0x18, 0xfc,
|
||||
0x34, 0x5b, 0x2d, 0x6b, 0xfa, 0x00, 0xba, 0xa5, 0xa8, 0xa3, 0x84, 0x1a, 0xb2, 0x67, 0xf0, 0x40,
|
||||
0x1b, 0x61, 0x0a, 0x6d, 0x17, 0x76, 0xc7, 0x2b, 0x54, 0xe6, 0x09, 0x85, 0x56, 0xb9, 0x95, 0x70,
|
||||
0xcb, 0x2b, 0xc4, 0x9e, 0xc3, 0x1d, 0xe1, 0x6f, 0xf5, 0x03, 0xd7, 0x53, 0x53, 0x91, 0x1f, 0x13,
|
||||
0xd1, 0x6b, 0xf0, 0xf7, 0xb4, 0xd5, 0xd6, 0x42, 0x78, 0x48, 0x55, 0x5c, 0x11, 0x1f, 0xf0, 0x64,
|
||||
0xe7, 0xc2, 0x93, 0xc6, 0xea, 0xa6, 0x85, 0xf9, 0xae, 0x28, 0x33, 0x7f, 0xd8, 0x17, 0xe8, 0xb7,
|
||||
0x38, 0xc1, 0x86, 0x89, 0x14, 0xc9, 0x85, 0x17, 0x11, 0xbe, 0x38, 0x14, 0xdb, 0xfd, 0x8b, 0x3a,
|
||||
0x6c, 0x03, 0x2f, 0xaf, 0xda, 0xc5, 0xde, 0xb4, 0x91, 0x5c, 0x72, 0x35, 0xec, 0x25, 0xf6, 0xbd,
|
||||
0x36, 0x5a, 0xa3, 0x0e, 0x7b, 0x0b, 0x7e, 0xd3, 0x02, 0x36, 0x28, 0xaf, 0x6c, 0x31, 0x25, 0xbc,
|
||||
0x2f, 0x0b, 0xcd, 0x75, 0x45, 0x9d, 0xc9, 0x47, 0x78, 0x54, 0x66, 0xaa, 0x76, 0x45, 0xff, 0x75,
|
||||
0xdb, 0xbb, 0xee, 0xd7, 0x5b, 0xfb, 0x97, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x16, 0x85,
|
||||
0x42, 0x7a, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -338,7 +337,6 @@ const _ = grpc.SupportPackageIsVersion4
|
|||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type CertificateAuthorityClient interface {
|
||||
IssueCertificate(ctx context.Context, in *IssueCertificateRequest, opts ...grpc.CallOption) (*proto1.Certificate, error)
|
||||
IssuePrecertificate(ctx context.Context, in *IssueCertificateRequest, opts ...grpc.CallOption) (*IssuePrecertificateResponse, error)
|
||||
IssueCertificateForPrecertificate(ctx context.Context, in *IssueCertificateForPrecertificateRequest, opts ...grpc.CallOption) (*proto1.Certificate, error)
|
||||
GenerateOCSP(ctx context.Context, in *GenerateOCSPRequest, opts ...grpc.CallOption) (*OCSPResponse, error)
|
||||
|
@ -352,15 +350,6 @@ func NewCertificateAuthorityClient(cc *grpc.ClientConn) CertificateAuthorityClie
|
|||
return &certificateAuthorityClient{cc}
|
||||
}
|
||||
|
||||
func (c *certificateAuthorityClient) IssueCertificate(ctx context.Context, in *IssueCertificateRequest, opts ...grpc.CallOption) (*proto1.Certificate, error) {
|
||||
out := new(proto1.Certificate)
|
||||
err := c.cc.Invoke(ctx, "/ca.CertificateAuthority/IssueCertificate", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *certificateAuthorityClient) IssuePrecertificate(ctx context.Context, in *IssueCertificateRequest, opts ...grpc.CallOption) (*IssuePrecertificateResponse, error) {
|
||||
out := new(IssuePrecertificateResponse)
|
||||
err := c.cc.Invoke(ctx, "/ca.CertificateAuthority/IssuePrecertificate", in, out, opts...)
|
||||
|
@ -390,7 +379,6 @@ func (c *certificateAuthorityClient) GenerateOCSP(ctx context.Context, in *Gener
|
|||
|
||||
// CertificateAuthorityServer is the server API for CertificateAuthority service.
|
||||
type CertificateAuthorityServer interface {
|
||||
IssueCertificate(context.Context, *IssueCertificateRequest) (*proto1.Certificate, error)
|
||||
IssuePrecertificate(context.Context, *IssueCertificateRequest) (*IssuePrecertificateResponse, error)
|
||||
IssueCertificateForPrecertificate(context.Context, *IssueCertificateForPrecertificateRequest) (*proto1.Certificate, error)
|
||||
GenerateOCSP(context.Context, *GenerateOCSPRequest) (*OCSPResponse, error)
|
||||
|
@ -400,9 +388,6 @@ type CertificateAuthorityServer interface {
|
|||
type UnimplementedCertificateAuthorityServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedCertificateAuthorityServer) IssueCertificate(ctx context.Context, req *IssueCertificateRequest) (*proto1.Certificate, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method IssueCertificate not implemented")
|
||||
}
|
||||
func (*UnimplementedCertificateAuthorityServer) IssuePrecertificate(ctx context.Context, req *IssueCertificateRequest) (*IssuePrecertificateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method IssuePrecertificate not implemented")
|
||||
}
|
||||
|
@ -417,24 +402,6 @@ func RegisterCertificateAuthorityServer(s *grpc.Server, srv CertificateAuthority
|
|||
s.RegisterService(&_CertificateAuthority_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _CertificateAuthority_IssueCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(IssueCertificateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CertificateAuthorityServer).IssueCertificate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/ca.CertificateAuthority/IssueCertificate",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CertificateAuthorityServer).IssueCertificate(ctx, req.(*IssueCertificateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _CertificateAuthority_IssuePrecertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(IssueCertificateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -493,10 +460,6 @@ var _CertificateAuthority_serviceDesc = grpc.ServiceDesc{
|
|||
ServiceName: "ca.CertificateAuthority",
|
||||
HandlerType: (*CertificateAuthorityServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "IssueCertificate",
|
||||
Handler: _CertificateAuthority_IssueCertificate_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "IssuePrecertificate",
|
||||
Handler: _CertificateAuthority_IssuePrecertificate_Handler,
|
||||
|
|
|
@ -7,7 +7,6 @@ import "core/proto/core.proto";
|
|||
|
||||
// CertificateAuthority issues certificates.
|
||||
service CertificateAuthority {
|
||||
rpc IssueCertificate(IssueCertificateRequest) returns (core.Certificate) {}
|
||||
rpc IssuePrecertificate(IssueCertificateRequest) returns (IssuePrecertificateResponse) {}
|
||||
rpc IssueCertificateForPrecertificate(IssueCertificateForPrecertificateRequest) returns (core.Certificate) {}
|
||||
rpc GenerateOCSP(GenerateOCSPRequest) returns (OCSPResponse) {}
|
||||
|
|
|
@ -92,9 +92,6 @@ type RegistrationAuthority interface {
|
|||
|
||||
// CertificateAuthority defines the public interface for the Boulder CA
|
||||
type CertificateAuthority interface {
|
||||
// [RegistrationAuthority]
|
||||
IssueCertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest) (Certificate, error)
|
||||
|
||||
// [RegistrationAuthority]
|
||||
IssuePrecertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest) (*caPB.IssuePrecertificateResponse, error)
|
||||
|
||||
|
|
|
@ -34,17 +34,6 @@ func NewCertificateAuthorityClient(inner caPB.CertificateAuthorityClient, innerO
|
|||
return &CertificateAuthorityClientWrapper{inner, innerOCSP}
|
||||
}
|
||||
|
||||
func (cac CertificateAuthorityClientWrapper) IssueCertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest) (core.Certificate, error) {
|
||||
if cac.inner == nil {
|
||||
return core.Certificate{}, errors.New("this CA client does not support issuing certificates")
|
||||
}
|
||||
res, err := cac.inner.IssueCertificate(ctx, issueReq)
|
||||
if err != nil {
|
||||
return core.Certificate{}, err
|
||||
}
|
||||
return pbToCert(res)
|
||||
}
|
||||
|
||||
func (cac CertificateAuthorityClientWrapper) IssuePrecertificate(ctx context.Context, issueReq *caPB.IssueCertificateRequest) (*caPB.IssuePrecertificateResponse, error) {
|
||||
if cac.inner == nil {
|
||||
return nil, errors.New("this CA client does not support issuing precertificates")
|
||||
|
@ -102,14 +91,6 @@ func NewCertificateAuthorityServer(inner core.CertificateAuthority) *Certificate
|
|||
return &CertificateAuthorityServerWrapper{inner}
|
||||
}
|
||||
|
||||
func (cas *CertificateAuthorityServerWrapper) IssueCertificate(ctx context.Context, request *caPB.IssueCertificateRequest) (*corepb.Certificate, error) {
|
||||
cert, err := cas.inner.IssueCertificate(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return certToPB(cert), nil
|
||||
}
|
||||
|
||||
func (cas *CertificateAuthorityServerWrapper) IssuePrecertificate(ctx context.Context, request *caPB.IssueCertificateRequest) (*caPB.IssuePrecertificateResponse, error) {
|
||||
if request == nil || request.Csr == nil || request.OrderID == nil || request.RegistrationID == nil {
|
||||
return nil, errIncompleteRequest
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
"backdate": "1h",
|
||||
"lifespanOCSP": "96h",
|
||||
"maxNames": 100,
|
||||
"enableMustStaple": true,
|
||||
"hostnamePolicyFile": "test/hostname-policy.yaml",
|
||||
"cfssl": {
|
||||
"signing": {
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
"backdate": "1h",
|
||||
"lifespanOCSP": "96h",
|
||||
"maxNames": 100,
|
||||
"enableMustStaple": true,
|
||||
"hostnamePolicyFile": "test/hostname-policy.yaml",
|
||||
"cfssl": {
|
||||
"signing": {
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
"backdate": "1h",
|
||||
"lifespanOCSP": "96h",
|
||||
"maxNames": 100,
|
||||
"enableMustStaple": true,
|
||||
"hostnamePolicyFile": "test/hostname-policy.yaml",
|
||||
"cfssl": {
|
||||
"signing": {
|
||||
|
|
Loading…
Reference in New Issue