Skip to content

Commit 585319f

Browse files
authored
issuance: remove profile hashes (#8118)
Part of #8039
1 parent 23e14f1 commit 585319f

File tree

5 files changed

+40
-166
lines changed

5 files changed

+40
-166
lines changed

ca/ca.go

Lines changed: 11 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ type issuanceEvent struct {
6060
Issuer string
6161
OrderID int64
6262
Profile string
63-
ProfileHash string
6463
Requester int64
6564
Result struct {
6665
Precertificate string `json:",omitempty"`
@@ -79,20 +78,10 @@ type issuerMaps struct {
7978

8079
type certProfileWithID struct {
8180
// name is a human readable name used to refer to the certificate profile.
82-
name string
83-
// hash is SHA256 sum over every exported field of an issuance.ProfileConfig
84-
// used to generate the embedded *issuance.Profile.
85-
hash [32]byte
81+
name string
8682
profile *issuance.Profile
8783
}
8884

89-
// certProfilesMaps allows looking up the human-readable name of a certificate
90-
// profile to retrieve the actual profile.
91-
type certProfilesMaps struct {
92-
profileByHash map[[32]byte]*certProfileWithID
93-
profileByName map[string]*certProfileWithID
94-
}
95-
9685
// caMetrics holds various metrics which are shared between caImpl, ocspImpl,
9786
// and crlImpl.
9887
type caMetrics struct {
@@ -150,7 +139,7 @@ type certificateAuthorityImpl struct {
150139
sctClient rapb.SCTProviderClient
151140
pa core.PolicyAuthority
152141
issuers issuerMaps
153-
certProfiles certProfilesMaps
142+
certProfiles map[string]*certProfileWithID
154143

155144
// The prefix is prepended to the serial number.
156145
prefix byte
@@ -190,46 +179,27 @@ func makeIssuerMaps(issuers []*issuance.Issuer) (issuerMaps, error) {
190179
}
191180

192181
// makeCertificateProfilesMap processes a set of named certificate issuance
193-
// profile configs into a two pre-computed maps: 1) a human-readable name to the
194-
// profile and 2) a unique hash over contents of the profile to the profile
195-
// itself. It returns the maps or an error if a duplicate name or hash is found.
196-
//
197-
// The unique hash is used in the case of
198-
// - RA instructs CA1 to issue a precertificate
199-
// - CA1 returns the precertificate DER bytes and profile hash to the RA
200-
// - RA instructs CA2 to issue a final certificate, but CA2 does not contain a
201-
// profile corresponding to that hash and an issuance is prevented.
202-
func makeCertificateProfilesMap(profiles map[string]*issuance.ProfileConfig) (certProfilesMaps, error) {
182+
// profile configs into a map from name to profile.
183+
func makeCertificateProfilesMap(profiles map[string]*issuance.ProfileConfig) (map[string]*certProfileWithID, error) {
203184
if len(profiles) <= 0 {
204-
return certProfilesMaps{}, fmt.Errorf("must pass at least one certificate profile")
185+
return nil, fmt.Errorf("must pass at least one certificate profile")
205186
}
206187

207188
profilesByName := make(map[string]*certProfileWithID, len(profiles))
208-
profilesByHash := make(map[[32]byte]*certProfileWithID, len(profiles))
209189

210190
for name, profileConfig := range profiles {
211191
profile, err := issuance.NewProfile(profileConfig)
212192
if err != nil {
213-
return certProfilesMaps{}, err
193+
return nil, err
214194
}
215195

216-
hash := profile.Hash()
217-
218-
withID := certProfileWithID{
196+
profilesByName[name] = &certProfileWithID{
219197
name: name,
220-
hash: hash,
221198
profile: profile,
222199
}
223-
224-
profilesByName[name] = &withID
225-
_, found := profilesByHash[hash]
226-
if found {
227-
return certProfilesMaps{}, fmt.Errorf("duplicate certificate profile hash %d", hash)
228-
}
229-
profilesByHash[hash] = &withID
230200
}
231201

232-
return certProfilesMaps{profilesByHash, profilesByName}, nil
202+
return profilesByName, nil
233203
}
234204

235205
// NewCertificateAuthorityImpl creates a CA instance that can sign certificates
@@ -300,8 +270,7 @@ var ocspStatusToCode = map[string]int{
300270
// precertificate.
301271
//
302272
// Subsequent final issuance based on this precertificate must happen at most once, and must use the same
303-
// certificate profile. The certificate profile is identified by a hash to ensure an exact match even if
304-
// the configuration for a specific profile _name_ changes.
273+
// certificate profile.
305274
//
306275
// Returns precertificate DER.
307276
//
@@ -349,7 +318,7 @@ func (ca *certificateAuthorityImpl) IssueCertificate(ctx context.Context, issueR
349318
}
350319

351320
// All issuance requests must come with a profile name, and the RA handles selecting the default.
352-
certProfile, ok := ca.certProfiles.profileByName[issueReq.CertProfileName]
321+
certProfile, ok := ca.certProfiles[issueReq.CertProfileName]
353322
if !ok {
354323
return nil, fmt.Errorf("the CA is incapable of using a profile named %s", issueReq.CertProfileName)
355324
}
@@ -444,7 +413,6 @@ func (ca *certificateAuthorityImpl) issueCertificateForPrecertificate(ctx contex
444413
Issuer: issuer.Name(),
445414
OrderID: orderID,
446415
Profile: certProfile.name,
447-
ProfileHash: hex.EncodeToString(certProfile.hash[:]),
448416
Requester: regID,
449417
}
450418
ca.log.AuditObject("Signing cert", logEvent)
@@ -611,7 +579,6 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
611579
IssuanceRequest: req,
612580
Issuer: issuer.Name(),
613581
Profile: certProfile.name,
614-
ProfileHash: hex.EncodeToString(certProfile.hash[:]),
615582
Requester: issueReq.RegistrationID,
616583
OrderID: issueReq.OrderID,
617584
}
@@ -645,7 +612,7 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
645612
logEvent.CSR = ""
646613
ca.log.AuditObject("Signing precert success", logEvent)
647614

648-
return certDER, &certProfileWithID{certProfile.name, certProfile.hash, nil}, nil
615+
return certDER, &certProfileWithID{certProfile.name, nil}, nil
649616
}
650617

651618
// verifyTBSCertIsDeterministic verifies that x509.CreateCertificate signing

ca/ca_test.go

Lines changed: 17 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func TestIssuePrecertificate(t *testing.T) {
333333
test.AssertNotError(t, err, "Certificate request failed to parse")
334334
issueReq := &capb.IssueCertificateRequest{Csr: testCase.csr, RegistrationID: mrand.Int63(), OrderID: mrand.Int63()}
335335

336-
profile := ca.certProfiles.profileByName["legacy"]
336+
profile := ca.certProfiles["legacy"]
337337
certDER, err := ca.issuePrecertificate(ctx, profile, issueReq)
338338
test.AssertNotError(t, err, "Failed to issue precertificate")
339339

@@ -444,7 +444,7 @@ func TestMultipleIssuers(t *testing.T) {
444444
test.AssertNotError(t, err, "Failed to remake CA")
445445

446446
// Test that an RSA CSR gets issuance from an RSA issuer.
447-
profile := ca.certProfiles.profileByName["legacy"]
447+
profile := ca.certProfiles["legacy"]
448448
issuedCertDER, err := ca.issuePrecertificate(ctx, profile, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: mrand.Int63(), OrderID: mrand.Int63()})
449449
test.AssertNotError(t, err, "Failed to issue certificate")
450450
cert, err := x509.ParseCertificate(issuedCertDER)
@@ -529,7 +529,7 @@ func TestUnpredictableIssuance(t *testing.T) {
529529
req := &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: mrand.Int63(), OrderID: mrand.Int63()}
530530
seenE2 := false
531531
seenR3 := false
532-
profile := ca.certProfiles.profileByName["legacy"]
532+
profile := ca.certProfiles["legacy"]
533533
for i := 0; i < 20; i++ {
534534
precertDER, err := ca.issuePrecertificate(ctx, profile, req)
535535
test.AssertNotError(t, err, "Failed to issue test certificate")
@@ -552,22 +552,11 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
552552
testCtx := setup(t)
553553
test.AssertEquals(t, len(testCtx.certProfiles), 2)
554554

555-
testProfile := issuance.ProfileConfig{
556-
AllowMustStaple: false,
557-
MaxValidityPeriod: config.Duration{Duration: time.Hour * 24 * 90},
558-
MaxValidityBackdate: config.Duration{Duration: time.Hour},
559-
}
560-
561-
type nameToHash struct {
562-
name string
563-
hash [32]byte
564-
}
565-
566555
testCases := []struct {
567556
name string
568557
profileConfigs map[string]*issuance.ProfileConfig
569558
expectedErrSubstr string
570-
expectedProfiles []nameToHash
559+
expectedProfiles []string
571560
}{
572561
{
573562
name: "nil profile map",
@@ -579,39 +568,17 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
579568
profileConfigs: map[string]*issuance.ProfileConfig{},
580569
expectedErrSubstr: "at least one certificate profile",
581570
},
582-
{
583-
name: "duplicate hash",
584-
profileConfigs: map[string]*issuance.ProfileConfig{
585-
"default": &testProfile,
586-
"default2": &testProfile,
587-
},
588-
expectedErrSubstr: "duplicate certificate profile hash",
589-
},
590571
{
591572
name: "empty profile config",
592573
profileConfigs: map[string]*issuance.ProfileConfig{
593574
"empty": {},
594575
},
595-
expectedProfiles: []nameToHash{
596-
{
597-
name: "empty",
598-
hash: [32]byte{0xe4, 0xf6, 0xd, 0xa, 0xa6, 0xd7, 0xf3, 0xd3, 0xb6, 0xa6, 0x49, 0x4b, 0x1c, 0x86, 0x1b, 0x99, 0xf6, 0x49, 0xc6, 0xf9, 0xec, 0x51, 0xab, 0xaf, 0x20, 0x1b, 0x20, 0xf2, 0x97, 0x32, 0x7c, 0x95},
599-
},
600-
},
576+
expectedProfiles: []string{"empty"},
601577
},
602578
{
603-
name: "default profiles from setup func",
604-
profileConfigs: testCtx.certProfiles,
605-
expectedProfiles: []nameToHash{
606-
{
607-
name: "legacy",
608-
hash: [32]byte{0xb7, 0xd9, 0x7e, 0xfc, 0x5a, 0xdd, 0xc7, 0xfe, 0xc, 0xea, 0xed, 0x7b, 0x8c, 0xf5, 0x4, 0x57, 0x71, 0x97, 0x42, 0x80, 0xbe, 0x4d, 0x14, 0xa, 0x35, 0x9a, 0x89, 0xc3, 0x7a, 0x57, 0x41, 0xb7},
609-
},
610-
{
611-
name: "modern",
612-
hash: [32]byte{0x2e, 0x82, 0x9b, 0xe4, 0x4d, 0xac, 0xfc, 0x2d, 0x83, 0xbf, 0x62, 0xe5, 0xe1, 0x50, 0xe8, 0xba, 0xd2, 0x66, 0x1a, 0xb3, 0xf2, 0xe7, 0xb5, 0xf2, 0x24, 0x94, 0x1f, 0x83, 0xc6, 0x57, 0xe, 0x58},
613-
},
614-
},
579+
name: "default profiles from setup func",
580+
profileConfigs: testCtx.certProfiles,
581+
expectedProfiles: []string{"legacy", "modern"},
615582
},
616583
}
617584

@@ -628,17 +595,14 @@ func TestMakeCertificateProfilesMap(t *testing.T) {
628595
}
629596

630597
if tc.expectedProfiles != nil {
631-
test.AssertEquals(t, len(profiles.profileByName), len(tc.expectedProfiles))
598+
test.AssertEquals(t, len(profiles), len(tc.expectedProfiles))
632599
}
633600

634601
for _, expected := range tc.expectedProfiles {
635-
cpwid, ok := profiles.profileByName[expected.name]
636-
test.Assert(t, ok, fmt.Sprintf("expected profile %q not found", expected.name))
637-
test.AssertEquals(t, cpwid.hash, expected.hash)
602+
cpwid, ok := profiles[expected]
603+
test.Assert(t, ok, fmt.Sprintf("expected profile %q not found", expected))
638604

639-
cpwid, ok = profiles.profileByHash[expected.hash]
640-
test.Assert(t, ok, fmt.Sprintf("expected profile %q not found", expected.hash))
641-
test.AssertEquals(t, cpwid.name, expected.name)
605+
test.AssertEquals(t, cpwid.name, expected)
642606
}
643607
})
644608
}
@@ -711,7 +675,7 @@ func TestInvalidCSRs(t *testing.T) {
711675
t.Run(testCase.name, func(t *testing.T) {
712676
t.Parallel()
713677
serializedCSR := mustRead(testCase.csrPath)
714-
profile := ca.certProfiles.profileByName["legacy"]
678+
profile := ca.certProfiles["legacy"]
715679
issueReq := &capb.IssueCertificateRequest{Csr: serializedCSR, RegistrationID: mrand.Int63(), OrderID: mrand.Int63(), CertProfileName: "legacy"}
716680
_, err = ca.issuePrecertificate(ctx, profile, issueReq)
717681

@@ -749,7 +713,7 @@ func TestRejectValidityTooLong(t *testing.T) {
749713
test.AssertNotError(t, err, "Failed to create CA")
750714

751715
// Test that the CA rejects CSRs that would expire after the intermediate cert
752-
profile := ca.certProfiles.profileByName["legacy"]
716+
profile := ca.certProfiles["legacy"]
753717
_, err = ca.issuePrecertificate(ctx, profile, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: mrand.Int63(), OrderID: mrand.Int63(), CertProfileName: "legacy"})
754718
test.AssertError(t, err, "Cannot issue a certificate that expires after the intermediate certificate")
755719
test.AssertErrorIs(t, err, berrors.InternalServer)
@@ -842,7 +806,7 @@ func TestIssueCertificateForPrecertificate(t *testing.T) {
842806
testCtx.fc)
843807
test.AssertNotError(t, err, "Failed to create CA")
844808

845-
profile := ca.certProfiles.profileByName["legacy"]
809+
profile := ca.certProfiles["legacy"]
846810
issueReq := capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: mrand.Int63(), OrderID: mrand.Int63(), CertProfileName: "legacy"}
847811
precertDER, err := ca.issuePrecertificate(ctx, profile, &issueReq)
848812
test.AssertNotError(t, err, "Failed to issue precert")
@@ -905,7 +869,7 @@ func TestIssueCertificateForPrecertificateWithSpecificCertificateProfile(t *test
905869
test.AssertNotError(t, err, "Failed to create CA")
906870

907871
selectedProfile := "modern"
908-
certProfile, ok := ca.certProfiles.profileByName[selectedProfile]
872+
certProfile, ok := ca.certProfiles[selectedProfile]
909873
test.Assert(t, ok, "Certificate profile was expected to exist")
910874

911875
issueReq := capb.IssueCertificateRequest{
@@ -1024,7 +988,7 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
1024988
t.Fatal(err)
1025989
}
1026990

1027-
profile := ca.certProfiles.profileByName["legacy"]
991+
profile := ca.certProfiles["legacy"]
1028992
issueReq := capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: mrand.Int63(), OrderID: mrand.Int63(), CertProfileName: "legacy"}
1029993
precertDER, err := ca.issuePrecertificate(ctx, profile, &issueReq)
1030994
test.AssertNotError(t, err, "Failed to issue precert")

ca/ocsp_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestOCSP(t *testing.T) {
4545
test.AssertNotError(t, err, "Failed to create CA")
4646
ocspi := testCtx.ocsp
4747

48-
profile := ca.certProfiles.profileByName["legacy"]
48+
profile := ca.certProfiles["legacy"]
4949
// Issue a certificate from an RSA issuer, request OCSP from the same issuer,
5050
// and make sure it works.
5151
rsaCertDER, err := ca.issuePrecertificate(ctx, profile, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: mrand.Int63(), OrderID: mrand.Int63(), CertProfileName: "legacy"})

0 commit comments

Comments
 (0)