CA: Require RA to always provide profile name (#7991)
Deprecate the CA's DefaultCertificateProfileName config key, now that default profile selection is being handled by the RA instead. Part of https://github.com/letsencrypt/boulder/issues/7986
This commit is contained in:
parent
0efb2a026d
commit
a9e3ad1143
32
ca/ca.go
32
ca/ca.go
|
@ -87,13 +87,8 @@ type certProfileWithID struct {
|
|||
}
|
||||
|
||||
// certProfilesMaps allows looking up the human-readable name of a certificate
|
||||
// profile to retrieve the actual profile. The default profile to be used is
|
||||
// stored alongside the maps.
|
||||
// profile to retrieve the actual profile.
|
||||
type certProfilesMaps struct {
|
||||
// The name of the profile that will be selected if no explicit profile name
|
||||
// is provided via gRPC.
|
||||
defaultName string
|
||||
|
||||
profileByHash map[[32]byte]*certProfileWithID
|
||||
profileByName map[string]*certProfileWithID
|
||||
}
|
||||
|
@ -194,17 +189,11 @@ func makeIssuerMaps(issuers []*issuance.Issuer) (issuerMaps, error) {
|
|||
// - CA1 returns the precertificate DER bytes and profile hash to the RA
|
||||
// - RA instructs CA2 to issue a final certificate, but CA2 does not contain a
|
||||
// profile corresponding to that hash and an issuance is prevented.
|
||||
func makeCertificateProfilesMap(defaultName string, profiles map[string]*issuance.ProfileConfigNew) (certProfilesMaps, error) {
|
||||
func makeCertificateProfilesMap(profiles map[string]*issuance.ProfileConfigNew) (certProfilesMaps, error) {
|
||||
if len(profiles) <= 0 {
|
||||
return certProfilesMaps{}, fmt.Errorf("must pass at least one certificate profile")
|
||||
}
|
||||
|
||||
// Check that a profile exists with the configured default profile name.
|
||||
_, ok := profiles[defaultName]
|
||||
if !ok {
|
||||
return certProfilesMaps{}, fmt.Errorf("defaultCertificateProfileName:\"%s\" was configured, but a profile object was not found for that name", defaultName)
|
||||
}
|
||||
|
||||
profilesByName := make(map[string]*certProfileWithID, len(profiles))
|
||||
profilesByHash := make(map[[32]byte]*certProfileWithID, len(profiles))
|
||||
|
||||
|
@ -230,7 +219,7 @@ func makeCertificateProfilesMap(defaultName string, profiles map[string]*issuanc
|
|||
profilesByHash[hash] = &withID
|
||||
}
|
||||
|
||||
return certProfilesMaps{defaultName, profilesByHash, profilesByName}, nil
|
||||
return certProfilesMaps{profilesByHash, profilesByName}, nil
|
||||
}
|
||||
|
||||
// NewCertificateAuthorityImpl creates a CA instance that can sign certificates
|
||||
|
@ -240,7 +229,6 @@ func NewCertificateAuthorityImpl(
|
|||
sa sapb.StorageAuthorityCertificateClient,
|
||||
pa core.PolicyAuthority,
|
||||
boulderIssuers []*issuance.Issuer,
|
||||
defaultCertProfileName string,
|
||||
certificateProfiles map[string]*issuance.ProfileConfigNew,
|
||||
serialPrefix byte,
|
||||
maxNames int,
|
||||
|
@ -261,7 +249,7 @@ func NewCertificateAuthorityImpl(
|
|||
return nil, errors.New("must have at least one issuer")
|
||||
}
|
||||
|
||||
certProfiles, err := makeCertificateProfilesMap(defaultCertProfileName, certificateProfiles)
|
||||
certProfiles, err := makeCertificateProfilesMap(certificateProfiles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -306,18 +294,14 @@ var ocspStatusToCode = map[string]int{
|
|||
// [issuance cycle]: https://github.com/letsencrypt/boulder/blob/main/docs/ISSUANCE-CYCLE.md
|
||||
func (ca *certificateAuthorityImpl) IssuePrecertificate(ctx context.Context, issueReq *capb.IssueCertificateRequest) (*capb.IssuePrecertificateResponse, error) {
|
||||
// issueReq.orderID may be zero, for ACMEv1 requests.
|
||||
if core.IsAnyNilOrZero(issueReq, issueReq.Csr, issueReq.RegistrationID) {
|
||||
if core.IsAnyNilOrZero(issueReq, issueReq.Csr, issueReq.RegistrationID, issueReq.CertProfileName) {
|
||||
return nil, berrors.InternalServerError("Incomplete issue certificate request")
|
||||
}
|
||||
|
||||
// The CA must check if it is capable of issuing for the given certificate
|
||||
// profile name. The name is checked here instead of the hash because the RA
|
||||
// is unaware of what certificate profiles exist. Pre-existing orders stored
|
||||
// in the database may not have an associated certificate profile name and
|
||||
// will take the default name stored alongside the map.
|
||||
if issueReq.CertProfileName == "" {
|
||||
issueReq.CertProfileName = ca.certProfiles.defaultName
|
||||
}
|
||||
// profile name. We check the name here, because the RA is not able to
|
||||
// precompute profile hashes. All issuance requests must come with a profile
|
||||
// name, and the RA handles selecting the default.
|
||||
certProfile, ok := ca.certProfiles.profileByName[issueReq.CertProfileName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the CA is incapable of using a profile named %s", issueReq.CertProfileName)
|
||||
|
|
109
ca/ca_test.go
109
ca/ca_test.go
|
@ -98,18 +98,17 @@ func mustRead(path string) []byte {
|
|||
}
|
||||
|
||||
type testCtx struct {
|
||||
pa core.PolicyAuthority
|
||||
ocsp *ocspImpl
|
||||
crl *crlImpl
|
||||
defaultCertProfileName string
|
||||
certProfiles map[string]*issuance.ProfileConfigNew
|
||||
serialPrefix byte
|
||||
maxNames int
|
||||
boulderIssuers []*issuance.Issuer
|
||||
keyPolicy goodkey.KeyPolicy
|
||||
fc clock.FakeClock
|
||||
metrics *caMetrics
|
||||
logger *blog.Mock
|
||||
pa core.PolicyAuthority
|
||||
ocsp *ocspImpl
|
||||
crl *crlImpl
|
||||
certProfiles map[string]*issuance.ProfileConfigNew
|
||||
serialPrefix byte
|
||||
maxNames int
|
||||
boulderIssuers []*issuance.Issuer
|
||||
keyPolicy goodkey.KeyPolicy
|
||||
fc clock.FakeClock
|
||||
metrics *caMetrics
|
||||
logger *blog.Mock
|
||||
}
|
||||
|
||||
type mockSA struct {
|
||||
|
@ -232,18 +231,17 @@ func setup(t *testing.T) *testCtx {
|
|||
test.AssertNotError(t, err, "Failed to create crl impl")
|
||||
|
||||
return &testCtx{
|
||||
pa: pa,
|
||||
ocsp: ocsp,
|
||||
crl: crl,
|
||||
defaultCertProfileName: "legacy",
|
||||
certProfiles: certProfiles,
|
||||
serialPrefix: 0x11,
|
||||
maxNames: 2,
|
||||
boulderIssuers: boulderIssuers,
|
||||
keyPolicy: keyPolicy,
|
||||
fc: fc,
|
||||
metrics: cametrics,
|
||||
logger: blog.NewMock(),
|
||||
pa: pa,
|
||||
ocsp: ocsp,
|
||||
crl: crl,
|
||||
certProfiles: certProfiles,
|
||||
serialPrefix: 0x11,
|
||||
maxNames: 2,
|
||||
boulderIssuers: boulderIssuers,
|
||||
keyPolicy: keyPolicy,
|
||||
fc: fc,
|
||||
metrics: cametrics,
|
||||
logger: blog.NewMock(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +253,6 @@ func TestSerialPrefix(t *testing.T) {
|
|||
nil,
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
nil,
|
||||
0x00,
|
||||
testCtx.maxNames,
|
||||
|
@ -269,7 +266,6 @@ func TestSerialPrefix(t *testing.T) {
|
|||
nil,
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
nil,
|
||||
0x80,
|
||||
testCtx.maxNames,
|
||||
|
@ -328,7 +324,7 @@ func TestIssuePrecertificate(t *testing.T) {
|
|||
t.Parallel()
|
||||
req, err := x509.ParseCertificateRequest(testCase.csr)
|
||||
test.AssertNotError(t, err, "Certificate request failed to parse")
|
||||
issueReq := &capb.IssueCertificateRequest{Csr: testCase.csr, RegistrationID: arbitraryRegID}
|
||||
issueReq := &capb.IssueCertificateRequest{Csr: testCase.csr, RegistrationID: arbitraryRegID, CertProfileName: "legacy"}
|
||||
|
||||
var certDER []byte
|
||||
response, err := ca.IssuePrecertificate(ctx, issueReq)
|
||||
|
@ -365,7 +361,6 @@ func issueCertificateSubTestSetup(t *testing.T) (*certificateAuthorityImpl, *moc
|
|||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -404,7 +399,6 @@ func TestNoIssuers(t *testing.T) {
|
|||
sa,
|
||||
testCtx.pa,
|
||||
nil, // No issuers
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -425,7 +419,6 @@ func TestMultipleIssuers(t *testing.T) {
|
|||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -435,12 +428,8 @@ func TestMultipleIssuers(t *testing.T) {
|
|||
testCtx.fc)
|
||||
test.AssertNotError(t, err, "Failed to remake CA")
|
||||
|
||||
selectedProfile := ca.certProfiles.defaultName
|
||||
_, ok := ca.certProfiles.profileByName[selectedProfile]
|
||||
test.Assert(t, ok, "Certificate profile was expected to exist")
|
||||
|
||||
// Test that an RSA CSR gets issuance from an RSA issuer.
|
||||
issuedCert, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, CertProfileName: selectedProfile})
|
||||
issuedCert, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, CertProfileName: "legacy"})
|
||||
test.AssertNotError(t, err, "Failed to issue certificate")
|
||||
cert, err := x509.ParseCertificate(issuedCert.DER)
|
||||
test.AssertNotError(t, err, "Certificate failed to parse")
|
||||
|
@ -456,7 +445,7 @@ func TestMultipleIssuers(t *testing.T) {
|
|||
test.AssertMetricWithLabelsEquals(t, ca.metrics.signatureCount, prometheus.Labels{"purpose": "precertificate", "status": "success"}, 1)
|
||||
|
||||
// Test that an ECDSA CSR gets issuance from an ECDSA issuer.
|
||||
issuedCert, err = ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID, CertProfileName: selectedProfile})
|
||||
issuedCert, err = ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID, CertProfileName: "legacy"})
|
||||
test.AssertNotError(t, err, "Failed to issue certificate")
|
||||
cert, err = x509.ParseCertificate(issuedCert.DER)
|
||||
test.AssertNotError(t, err, "Certificate failed to parse")
|
||||
|
@ -499,7 +488,6 @@ func TestUnpredictableIssuance(t *testing.T) {
|
|||
sa,
|
||||
testCtx.pa,
|
||||
boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -521,7 +509,7 @@ func TestUnpredictableIssuance(t *testing.T) {
|
|||
// trials, the probability that all 20 issuances come from the same issuer is
|
||||
// 0.5 ^ 20 = 9.5e-7 ~= 1e-6 = 1 in a million, so we do not consider this test
|
||||
// to be flaky.
|
||||
req := &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID}
|
||||
req := &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID, CertProfileName: "legacy"}
|
||||
seenE2 := false
|
||||
seenR3 := false
|
||||
for i := 0; i < 20; i++ {
|
||||
|
@ -559,7 +547,6 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
|
|||
|
||||
testCases := []struct {
|
||||
name string
|
||||
defaultName string
|
||||
profileConfigs map[string]*issuance.ProfileConfigNew
|
||||
expectedErrSubstr string
|
||||
expectedProfiles []nameToHash
|
||||
|
@ -575,16 +562,7 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
|
|||
expectedErrSubstr: "at least one certificate profile",
|
||||
},
|
||||
{
|
||||
name: "no profile matching default name",
|
||||
defaultName: "default",
|
||||
profileConfigs: map[string]*issuance.ProfileConfigNew{
|
||||
"notDefault": &testProfile,
|
||||
},
|
||||
expectedErrSubstr: "profile object was not found for that name",
|
||||
},
|
||||
{
|
||||
name: "duplicate hash",
|
||||
defaultName: "default",
|
||||
name: "duplicate hash",
|
||||
profileConfigs: map[string]*issuance.ProfileConfigNew{
|
||||
"default": &testProfile,
|
||||
"default2": &testProfile,
|
||||
|
@ -592,8 +570,7 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
|
|||
expectedErrSubstr: "duplicate certificate profile hash",
|
||||
},
|
||||
{
|
||||
name: "empty profile config",
|
||||
defaultName: "empty",
|
||||
name: "empty profile config",
|
||||
profileConfigs: map[string]*issuance.ProfileConfigNew{
|
||||
"empty": {},
|
||||
},
|
||||
|
@ -606,7 +583,6 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "default profiles from setup func",
|
||||
defaultName: testCtx.defaultCertProfileName,
|
||||
profileConfigs: testCtx.certProfiles,
|
||||
expectedProfiles: []nameToHash{
|
||||
{
|
||||
|
@ -624,7 +600,7 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
|
|||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
profiles, err := makeCertificateProfilesMap(tc.defaultName, tc.profileConfigs)
|
||||
profiles, err := makeCertificateProfilesMap(tc.profileConfigs)
|
||||
|
||||
if tc.expectedErrSubstr != "" {
|
||||
test.AssertError(t, err, "profile construction should have failed")
|
||||
|
@ -704,7 +680,6 @@ func TestInvalidCSRs(t *testing.T) {
|
|||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -717,7 +692,7 @@ func TestInvalidCSRs(t *testing.T) {
|
|||
t.Run(testCase.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
serializedCSR := mustRead(testCase.csrPath)
|
||||
issueReq := &capb.IssueCertificateRequest{Csr: serializedCSR, RegistrationID: arbitraryRegID}
|
||||
issueReq := &capb.IssueCertificateRequest{Csr: serializedCSR, RegistrationID: arbitraryRegID, CertProfileName: "legacy"}
|
||||
_, err = ca.IssuePrecertificate(ctx, issueReq)
|
||||
|
||||
test.AssertErrorIs(t, err, testCase.errorType)
|
||||
|
@ -743,7 +718,6 @@ func TestRejectValidityTooLong(t *testing.T) {
|
|||
&mockSA{},
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -754,7 +728,7 @@ func TestRejectValidityTooLong(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
|
||||
// Test that the CA rejects CSRs that would expire after the intermediate cert
|
||||
_, err = ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID})
|
||||
_, err = ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, CertProfileName: "legacy"})
|
||||
test.AssertError(t, err, "Cannot issue a certificate that expires after the intermediate certificate")
|
||||
test.AssertErrorIs(t, err, berrors.InternalServer)
|
||||
}
|
||||
|
@ -836,7 +810,6 @@ func TestIssueCertificateForPrecertificate(t *testing.T) {
|
|||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -846,10 +819,7 @@ func TestIssueCertificateForPrecertificate(t *testing.T) {
|
|||
testCtx.fc)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
|
||||
_, ok := ca.certProfiles.profileByName[ca.certProfiles.defaultName]
|
||||
test.Assert(t, ok, "Certificate profile was expected to exist")
|
||||
|
||||
issueReq := capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, OrderID: 0}
|
||||
issueReq := capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, OrderID: 0, CertProfileName: "legacy"}
|
||||
precert, err := ca.IssuePrecertificate(ctx, &issueReq)
|
||||
test.AssertNotError(t, err, "Failed to issue precert")
|
||||
parsedPrecert, err := x509.ParseCertificate(precert.DER)
|
||||
|
@ -901,7 +871,6 @@ func TestIssueCertificateForPrecertificateWithSpecificCertificateProfile(t *test
|
|||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -911,7 +880,7 @@ func TestIssueCertificateForPrecertificateWithSpecificCertificateProfile(t *test
|
|||
testCtx.fc)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
|
||||
selectedProfile := "legacy"
|
||||
selectedProfile := "modern"
|
||||
certProfile, ok := ca.certProfiles.profileByName[selectedProfile]
|
||||
test.Assert(t, ok, "Certificate profile was expected to exist")
|
||||
|
||||
|
@ -1017,7 +986,6 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
|
|||
sa,
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -1032,11 +1000,7 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
selectedProfile := ca.certProfiles.defaultName
|
||||
certProfile, ok := ca.certProfiles.profileByName[selectedProfile]
|
||||
test.Assert(t, ok, "Certificate profile was expected to exist")
|
||||
|
||||
issueReq := capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, OrderID: 0}
|
||||
issueReq := capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, OrderID: 0, CertProfileName: "legacy"}
|
||||
precert, err := ca.IssuePrecertificate(ctx, &issueReq)
|
||||
test.AssertNotError(t, err, "Failed to issue precert")
|
||||
test.AssertMetricWithLabelsEquals(t, ca.metrics.signatureCount, prometheus.Labels{"purpose": "precertificate", "status": "success"}, 1)
|
||||
|
@ -1045,7 +1009,7 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
|
|||
SCTs: sctBytes,
|
||||
RegistrationID: arbitraryRegID,
|
||||
OrderID: 0,
|
||||
CertProfileHash: certProfile.hash[:],
|
||||
CertProfileHash: ca.certProfiles.profileByName["legacy"].hash[:],
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("Expected error issuing duplicate serial but got none.")
|
||||
|
@ -1064,7 +1028,6 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
|
|||
errorsa,
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -1079,7 +1042,7 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
|
|||
SCTs: sctBytes,
|
||||
RegistrationID: arbitraryRegID,
|
||||
OrderID: 0,
|
||||
CertProfileHash: certProfile.hash[:],
|
||||
CertProfileHash: ca.certProfiles.profileByName["legacy"].hash[:],
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("Expected error issuing duplicate serial but got none.")
|
||||
|
|
|
@ -33,7 +33,6 @@ func TestOCSP(t *testing.T) {
|
|||
&mockSA{},
|
||||
testCtx.pa,
|
||||
testCtx.boulderIssuers,
|
||||
testCtx.defaultCertProfileName,
|
||||
testCtx.certProfiles,
|
||||
testCtx.serialPrefix,
|
||||
testCtx.maxNames,
|
||||
|
@ -46,7 +45,7 @@ func TestOCSP(t *testing.T) {
|
|||
|
||||
// Issue a certificate from an RSA issuer, request OCSP from the same issuer,
|
||||
// and make sure it works.
|
||||
rsaCertPB, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID})
|
||||
rsaCertPB, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, CertProfileName: "legacy"})
|
||||
test.AssertNotError(t, err, "Failed to issue certificate")
|
||||
rsaCert, err := x509.ParseCertificate(rsaCertPB.DER)
|
||||
test.AssertNotError(t, err, "Failed to parse rsaCert")
|
||||
|
@ -69,7 +68,7 @@ func TestOCSP(t *testing.T) {
|
|||
|
||||
// Issue a certificate from an ECDSA issuer, request OCSP from the same issuer,
|
||||
// and make sure it works.
|
||||
ecdsaCertPB, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID})
|
||||
ecdsaCertPB, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID, CertProfileName: "legacy"})
|
||||
test.AssertNotError(t, err, "Failed to issue certificate")
|
||||
ecdsaCert, err := x509.ParseCertificate(ecdsaCertPB.DER)
|
||||
test.AssertNotError(t, err, "Failed to parse ecdsaCert")
|
||||
|
|
|
@ -37,10 +37,12 @@ type Config struct {
|
|||
// The name of the certificate profile to use if one wasn't provided
|
||||
// by the RA during NewOrder and Finalize requests. Must match a
|
||||
// configured certificate profile or boulder-ca will fail to start.
|
||||
//
|
||||
// Deprecated: set the defaultProfileName in the RA config instead.
|
||||
DefaultCertificateProfileName string `validate:"omitempty,alphanum,min=1,max=32"`
|
||||
|
||||
// One of the profile names must match the value of
|
||||
// DefaultCertificateProfileName or boulder-ca will fail to start.
|
||||
// One of the profile names must match the value of ra.defaultProfileName
|
||||
// or large amounts of issuance will fail.
|
||||
CertProfiles map[string]*issuance.ProfileConfigNew `validate:"dive,keys,alphanum,min=1,max=32,endkeys,required_without=Profile,structonly"`
|
||||
|
||||
// TODO(#7159): Make this required once all live configs are using it.
|
||||
|
@ -194,11 +196,6 @@ func main() {
|
|||
logger.Infof("Loaded issuer: name=[%s] keytype=[%s] nameID=[%v] isActive=[%t]", issuer.Name(), issuer.KeyType(), issuer.NameID(), issuer.IsActive())
|
||||
}
|
||||
|
||||
if c.CA.Issuance.DefaultCertificateProfileName == "" {
|
||||
c.CA.Issuance.DefaultCertificateProfileName = "defaultBoulderCertificateProfile"
|
||||
}
|
||||
logger.Infof("Configured default certificate profile name set to: %s", c.CA.Issuance.DefaultCertificateProfileName)
|
||||
|
||||
if len(c.CA.Issuance.CertProfiles) == 0 {
|
||||
cmd.Fail("At least one profile must be configured")
|
||||
}
|
||||
|
@ -251,7 +248,6 @@ func main() {
|
|||
sa,
|
||||
pa,
|
||||
issuers,
|
||||
c.CA.Issuance.DefaultCertificateProfileName,
|
||||
c.CA.Issuance.CertProfiles,
|
||||
serialPrefix,
|
||||
c.CA.MaxNames,
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
"hostOverride": "sa.boulder"
|
||||
},
|
||||
"issuance": {
|
||||
"defaultCertificateProfileName": "legacy",
|
||||
"certProfiles": {
|
||||
"legacy": {
|
||||
"allowMustStaple": true,
|
||||
|
|
|
@ -29,12 +29,9 @@
|
|||
"debugAddr": ":8002",
|
||||
"hostnamePolicyFile": "test/hostname-policy.yaml",
|
||||
"maxNames": 100,
|
||||
"authorizationLifetimeDays": 30,
|
||||
"pendingAuthorizationLifetimeDays": 7,
|
||||
"goodkey": {
|
||||
"fermatRounds": 100
|
||||
},
|
||||
"orderLifetime": "168h",
|
||||
"issuerCerts": [
|
||||
"test/certs/webpki/int-rsa-a.cert.pem",
|
||||
"test/certs/webpki/int-rsa-b.cert.pem",
|
||||
|
@ -43,6 +40,19 @@
|
|||
"test/certs/webpki/int-ecdsa-b.cert.pem",
|
||||
"test/certs/webpki/int-ecdsa-c.cert.pem"
|
||||
],
|
||||
"validationProfiles": {
|
||||
"legacy": {
|
||||
"pendingAuthzLifetime": "168h",
|
||||
"validAuthzLifetime": "720h",
|
||||
"orderLifetime": "168h"
|
||||
},
|
||||
"modern": {
|
||||
"pendingAuthzLifetime": "7h",
|
||||
"validAuthzLifetime": "7h",
|
||||
"orderLifetime": "7h"
|
||||
}
|
||||
},
|
||||
"defaultProfileName": "legacy",
|
||||
"tls": {
|
||||
"caCertFile": "test/certs/ipki/minica.pem",
|
||||
"certFile": "test/certs/ipki/ra.boulder/cert.pem",
|
||||
|
|
Loading…
Reference in New Issue