Skip to content

Commit aa52a22

Browse files
committed
add constructore, make fields private
1 parent 8ee5d18 commit aa52a22

File tree

6 files changed

+75
-65
lines changed

6 files changed

+75
-65
lines changed

ctlog.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
"strings"
2424
"time"
2525

26+
"github.com/google/certificate-transparency-go/asn1"
27+
"github.com/google/certificate-transparency-go/x509"
2628
"github.com/google/certificate-transparency-go/x509util"
2729
"github.com/transparency-dev/static-ct/internal/scti"
2830
"github.com/transparency-dev/static-ct/storage"
@@ -91,34 +93,29 @@ func newCertValidationOpts(cfg ChainValidationConfig) (*scti.ChainValidationOpts
9193
return nil, fmt.Errorf("'Not After' limit %q before start %q", cfg.NotAfterLimit.Format(time.RFC3339), cfg.NotAfterStart.Format(time.RFC3339))
9294
}
9395

94-
validationOpts := scti.ChainValidationOpts{
95-
TrustedRoots: roots,
96-
RejectExpired: cfg.RejectExpired,
97-
RejectUnexpired: cfg.RejectUnexpired,
98-
NotAfterStart: cfg.NotAfterStart,
99-
NotAfterLimit: cfg.NotAfterLimit,
100-
}
101-
10296
var err error
97+
var extKeyUsages []x509.ExtKeyUsage
10398
// Filter which extended key usages are allowed.
10499
if cfg.ExtKeyUsages != "" {
105100
lExtKeyUsages := strings.Split(cfg.ExtKeyUsages, ",")
106-
validationOpts.ExtKeyUsages, err = scti.ParseExtKeyUsages(lExtKeyUsages)
101+
extKeyUsages, err = scti.ParseExtKeyUsages(lExtKeyUsages)
107102
if err != nil {
108103
return nil, fmt.Errorf("failed to parse ExtKeyUsages: %v", err)
109104
}
110105
}
111106

107+
var rejectExtIds []asn1.ObjectIdentifier
112108
// Filter which extensions are rejected.
113109
if cfg.RejectExtensions != "" {
114110
lRejectExtensions := strings.Split(cfg.RejectExtensions, ",")
115-
validationOpts.RejectExtIds, err = scti.ParseOIDs(lRejectExtensions)
111+
rejectExtIds, err = scti.ParseOIDs(lRejectExtensions)
116112
if err != nil {
117113
return nil, fmt.Errorf("failed to parse RejectExtensions: %v", err)
118114
}
119115
}
120116

121-
return &validationOpts, nil
117+
vOpts := scti.NewChainValidationOpts(roots, cfg.RejectExpired, cfg.RejectUnexpired, cfg.NotAfterStart, cfg.NotAfterLimit, extKeyUsages, rejectExtIds)
118+
return &vOpts, nil
122119
}
123120

124121
// NewLogHandler creates a Tessera based CT log pluged into HTTP handlers.

internal/scti/chain_validation.go

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,39 @@ func ParseOIDs(oids []string) ([]asn1.ObjectIdentifier, error) {
8787

8888
// ChainValidationOpts contains various parameters for certificate chain validation
8989
type ChainValidationOpts struct {
90-
// TrustedRoots is a pool of certificates that defines the roots the CT log will accept
91-
TrustedRoots *x509util.PEMCertPool
92-
// CurrentTime is the time used for checking a certificate's validity period
90+
// trustedRoots is a pool of certificates that defines the roots the CT log will accept
91+
trustedRoots *x509util.PEMCertPool
92+
// currentTime is the time used for checking a certificate's validity period
9393
// against. If it's zero then time.Now() is used. Only for testing.
94-
CurrentTime time.Time
95-
// RejectExpired indicates that expired certificates will be rejected.
96-
RejectExpired bool
97-
// RejectUnexpired indicates that certificates that are currently valid or not yet valid will be rejected.
98-
RejectUnexpired bool
99-
// NotAfterStart is the earliest notAfter date which will be accepted.
94+
currentTime time.Time
95+
// rejectExpired indicates that expired certificates will be rejected.
96+
rejectExpired bool
97+
// rejectUnexpired indicates that certificates that are currently valid or not yet valid will be rejected.
98+
rejectUnexpired bool
99+
// notAfterStart is the earliest notAfter date which will be accepted.
100100
// nil means no lower bound on the accepted range.
101-
NotAfterStart *time.Time
102-
// NotAfterLimit defines the cut off point of notAfter dates - only notAfter
103-
// dates strictly *before* NotAfterLimit will be accepted.
101+
notAfterStart *time.Time
102+
// notAfterLimit defines the cut off point of notAfter dates - only notAfter
103+
// dates strictly *before* notAfterLimit will be accepted.
104104
// nil means no upper bound on the accepted range.
105-
NotAfterLimit *time.Time
106-
// ExtKeyUsages contains the list of EKUs to use during chain verification
107-
ExtKeyUsages []x509.ExtKeyUsage
108-
// RejectExtIds contains a list of X.509 extension IDs to reject during chain verification.
109-
RejectExtIds []asn1.ObjectIdentifier
105+
notAfterLimit *time.Time
106+
// extKeyUsages contains the list of EKUs to use during chain verification
107+
extKeyUsages []x509.ExtKeyUsage
108+
// rejectExtIds contains a list of X.509 extension IDs to reject during chain verification.
109+
rejectExtIds []asn1.ObjectIdentifier
110+
}
111+
112+
func NewChainValidationOpts(trustedRoots *x509util.PEMCertPool, currentTime time.Time, rejectExpired, rejectUnexpired bool, notAfterStart, notAfterLimit *time.Time, extKeyUsages []x509.ExtKeyUsage, rejectExtIds []asn1.ObjectIdentifier) ChainValidationOpts {
113+
return ChainValidationOpts{
114+
trustedRoots: trustedRoots,
115+
currentTime: currentTime,
116+
rejectExpired: rejectExpired,
117+
rejectUnexpired: rejectUnexpired,
118+
notAfterStart: notAfterStart,
119+
notAfterLimit: notAfterLimit,
120+
extKeyUsages: extKeyUsages,
121+
rejectExtIds: rejectExtIds,
122+
}
110123
}
111124

112125
// isPrecertificate tests if a certificate is a pre-certificate as defined in CT.
@@ -151,8 +164,8 @@ func validateChain(rawChain [][]byte, validationOpts ChainValidationOpts) ([]*x5
151164
}
152165
}
153166

154-
naStart := validationOpts.NotAfterStart
155-
naLimit := validationOpts.NotAfterLimit
167+
naStart := validationOpts.notAfterStart
168+
naLimit := validationOpts.notAfterLimit
156169
cert := chain[0]
157170

158171
// Check whether the expiry date of the cert is within the acceptable range.
@@ -163,24 +176,24 @@ func validateChain(rawChain [][]byte, validationOpts ChainValidationOpts) ([]*x5
163176
return nil, fmt.Errorf("certificate NotAfter (%v) >= %v", cert.NotAfter, *naLimit)
164177
}
165178

166-
now := validationOpts.CurrentTime
179+
now := validationOpts.currentTime
167180
if now.IsZero() {
168181
now = time.Now()
169182
}
170183
expired := now.After(cert.NotAfter)
171-
if validationOpts.RejectExpired && expired {
184+
if validationOpts.rejectExpired && expired {
172185
return nil, errors.New("rejecting expired certificate")
173186
}
174-
if validationOpts.RejectUnexpired && !expired {
187+
if validationOpts.rejectUnexpired && !expired {
175188
return nil, errors.New("rejecting unexpired certificate")
176189
}
177190

178191
// Check for unwanted extension types, if required.
179192
// TODO(al): Refactor CertValidationOpts c'tor to a builder pattern and
180193
// pre-calc this in there
181-
if len(validationOpts.RejectExtIds) != 0 {
194+
if len(validationOpts.rejectExtIds) != 0 {
182195
badIDs := make(map[string]bool)
183-
for _, id := range validationOpts.RejectExtIds {
196+
for _, id := range validationOpts.rejectExtIds {
184197
badIDs[id.String()] = true
185198
}
186199
for idx, ext := range cert.Extensions {
@@ -193,9 +206,9 @@ func validateChain(rawChain [][]byte, validationOpts ChainValidationOpts) ([]*x5
193206

194207
// TODO(al): Refactor CertValidationOpts c'tor to a builder pattern and
195208
// pre-calc this in there too.
196-
if len(validationOpts.ExtKeyUsages) > 0 {
209+
if len(validationOpts.extKeyUsages) > 0 {
197210
acceptEKUs := make(map[x509.ExtKeyUsage]bool)
198-
for _, eku := range validationOpts.ExtKeyUsages {
211+
for _, eku := range validationOpts.extKeyUsages {
199212
acceptEKUs[eku] = true
200213
}
201214
good := false
@@ -206,14 +219,14 @@ func validateChain(rawChain [][]byte, validationOpts ChainValidationOpts) ([]*x5
206219
}
207220
}
208221
if !good {
209-
return nil, fmt.Errorf("rejecting certificate without EKU in %v", validationOpts.ExtKeyUsages)
222+
return nil, fmt.Errorf("rejecting certificate without EKU in %v", validationOpts.extKeyUsages)
210223
}
211224
}
212225

213226
// We can now do the verification. Use fairly lax options for verification, as
214227
// CT is intended to observe certificates rather than police them.
215228
verifyOpts := x509.VerifyOptions{
216-
Roots: validationOpts.TrustedRoots.CertPool(),
229+
Roots: validationOpts.trustedRoots.CertPool(),
217230
CurrentTime: now,
218231
Intermediates: intermediatePool.CertPool(),
219232
DisableTimeChecks: true,
@@ -232,7 +245,7 @@ func validateChain(rawChain [][]byte, validationOpts ChainValidationOpts) ([]*x5
232245
DisablePathLenChecks: true,
233246
DisableNameConstraintChecks: true,
234247
DisableNameChecks: false,
235-
KeyUsages: validationOpts.ExtKeyUsages,
248+
KeyUsages: validationOpts.extKeyUsages,
236249
}
237250

238251
verifiedChains, err := cert.Verify(verifyOpts)

internal/scti/chain_validation_test.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func TestValidateChain(t *testing.T) {
115115
t.Fatal("failed to load real intermediate")
116116
}
117117
validateOpts := ChainValidationOpts{
118-
TrustedRoots: fakeCARoots,
118+
trustedRoots: fakeCARoots,
119119
}
120120

121121
var tests = []struct {
@@ -185,7 +185,7 @@ func TestValidateChain(t *testing.T) {
185185
chain: pemsToDERChain(t, []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM}),
186186
modifyOpts: func(v *ChainValidationOpts) {
187187
// reject SubjectKeyIdentifier extension
188-
v.RejectExtIds = []asn1.ObjectIdentifier{[]int{99, 99, 99, 99}}
188+
v.rejectExtIds = []asn1.ObjectIdentifier{[]int{99, 99, 99, 99}}
189189
},
190190
wantPathLen: 3,
191191
},
@@ -194,7 +194,7 @@ func TestValidateChain(t *testing.T) {
194194
chain: pemsToDERChain(t, []string{testdata.PrecertPEMValid}),
195195
modifyOpts: func(v *ChainValidationOpts) {
196196
// reject SubjectKeyIdentifier extension
197-
v.RejectExtIds = []asn1.ObjectIdentifier{[]int{99, 99, 99, 99}}
197+
v.rejectExtIds = []asn1.ObjectIdentifier{[]int{99, 99, 99, 99}}
198198
},
199199
wantPathLen: 2,
200200
},
@@ -204,7 +204,7 @@ func TestValidateChain(t *testing.T) {
204204
wantErr: true,
205205
modifyOpts: func(v *ChainValidationOpts) {
206206
// reject SubjectKeyIdentifier extension
207-
v.RejectExtIds = []asn1.ObjectIdentifier{[]int{2, 5, 29, 14}}
207+
v.rejectExtIds = []asn1.ObjectIdentifier{[]int{2, 5, 29, 14}}
208208
},
209209
},
210210
{
@@ -213,7 +213,7 @@ func TestValidateChain(t *testing.T) {
213213
wantErr: true,
214214
modifyOpts: func(v *ChainValidationOpts) {
215215
// reject SubjectKeyIdentifier extension
216-
v.RejectExtIds = []asn1.ObjectIdentifier{[]int{2, 5, 29, 14}}
216+
v.rejectExtIds = []asn1.ObjectIdentifier{[]int{2, 5, 29, 14}}
217217
},
218218
},
219219
{
@@ -222,15 +222,15 @@ func TestValidateChain(t *testing.T) {
222222
wantErr: true,
223223
modifyOpts: func(v *ChainValidationOpts) {
224224
// reject cert without ExtKeyUsageEmailProtection
225-
v.ExtKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}
225+
v.extKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}
226226
},
227227
},
228228
{
229229
desc: "allow-eku-present-in-cert",
230230
chain: pemsToDERChain(t, []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM}),
231231
wantPathLen: 3,
232232
modifyOpts: func(v *ChainValidationOpts) {
233-
v.ExtKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
233+
v.extKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
234234
},
235235
},
236236
{
@@ -239,15 +239,15 @@ func TestValidateChain(t *testing.T) {
239239
wantErr: true,
240240
modifyOpts: func(v *ChainValidationOpts) {
241241
// reject cert without ExtKeyUsageEmailProtection
242-
v.ExtKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}
242+
v.extKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}
243243
},
244244
},
245245
{
246246
desc: "allow-eku-present-in-precert",
247247
chain: pemsToDERChain(t, []string{testdata.RealPrecertWithEKUPEM}),
248248
wantPathLen: 2,
249249
modifyOpts: func(v *ChainValidationOpts) {
250-
v.ExtKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
250+
v.extKeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
251251
},
252252
},
253253
}
@@ -284,8 +284,8 @@ func TestNotAfterRange(t *testing.T) {
284284
t.Fatal("failed to load fake root")
285285
}
286286
validateOpts := ChainValidationOpts{
287-
TrustedRoots: fakeCARoots,
288-
RejectExpired: false,
287+
trustedRoots: fakeCARoots,
288+
rejectExpired: false,
289289
}
290290

291291
chain := pemsToDERChain(t, []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM})
@@ -323,10 +323,10 @@ func TestNotAfterRange(t *testing.T) {
323323
for _, test := range tests {
324324
t.Run(test.desc, func(t *testing.T) {
325325
if !test.notAfterStart.IsZero() {
326-
validateOpts.NotAfterStart = &test.notAfterStart
326+
validateOpts.notAfterStart = &test.notAfterStart
327327
}
328328
if !test.notAfterLimit.IsZero() {
329-
validateOpts.NotAfterLimit = &test.notAfterLimit
329+
validateOpts.notAfterLimit = &test.notAfterLimit
330330
}
331331
gotPath, err := validateChain(test.chain, validateOpts)
332332
if err != nil {
@@ -351,8 +351,8 @@ func TestRejectExpiredUnexpired(t *testing.T) {
351351
// Validity period: May 13, 2016 - Jul 12, 2019.
352352
chain := pemsToDERChain(t, []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM})
353353
validateOpts := ChainValidationOpts{
354-
TrustedRoots: fakeCARoots,
355-
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
354+
trustedRoots: fakeCARoots,
355+
extKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
356356
}
357357
beforeValidPeriod := time.Date(1999, 1, 1, 0, 0, 0, 0, time.UTC)
358358
currentValidPeriod := time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC)
@@ -437,9 +437,9 @@ func TestRejectExpiredUnexpired(t *testing.T) {
437437
},
438438
} {
439439
t.Run(tc.desc, func(t *testing.T) {
440-
validateOpts.CurrentTime = tc.now
441-
validateOpts.RejectExpired = tc.rejectExpired
442-
validateOpts.RejectUnexpired = tc.rejectUnexpired
440+
validateOpts.currentTime = tc.now
441+
validateOpts.rejectExpired = tc.rejectExpired
442+
validateOpts.rejectUnexpired = tc.rejectUnexpired
443443
_, err := validateChain(chain, validateOpts)
444444
if err != nil {
445445
if len(tc.wantErr) == 0 {
@@ -528,8 +528,8 @@ func TestCMPreIssuedCert(t *testing.T) {
528528
} {
529529
t.Run(tc.desc, func(t *testing.T) {
530530
opts := ChainValidationOpts{
531-
TrustedRoots: cmRoot,
532-
ExtKeyUsages: tc.eku,
531+
trustedRoots: cmRoot,
532+
extKeyUsages: tc.eku,
533533
}
534534
chain, err := validateChain(rawChain, opts)
535535
if err != nil {

internal/scti/ctlog_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func TestNewLog(t *testing.T) {
3939
desc: "ok",
4040
origin: "testlog",
4141
cvOpts: ChainValidationOpts{
42-
TrustedRoots: roots,
42+
trustedRoots: roots,
4343
},
4444
signer: signer,
4545
},

internal/scti/handlers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ func addPreChain(ctx context.Context, opts *HandlerOptions, log *log, w http.Res
330330

331331
func getRoots(_ context.Context, opts *HandlerOptions, log *log, w http.ResponseWriter, _ *http.Request) (int, error) {
332332
// Pull out the raw certificates from the parsed versions
333-
rawCerts := make([][]byte, 0, len(log.chainValidationOpts.TrustedRoots.RawCertificates()))
334-
for _, cert := range log.chainValidationOpts.TrustedRoots.RawCertificates() {
333+
rawCerts := make([][]byte, 0, len(log.chainValidationOpts.trustedRoots.RawCertificates()))
334+
for _, cert := range log.chainValidationOpts.trustedRoots.RawCertificates() {
335335
rawCerts = append(rawCerts, cert.Raw)
336336
}
337337

internal/scti/handlers_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ func setupTest(t *testing.T, pemRoots []string, signer crypto.Signer) handlerTes
9191

9292
info.storage = mockstorage.NewMockStorage(info.mockCtrl)
9393
vOpts := ChainValidationOpts{
94-
TrustedRoots: info.roots,
95-
RejectExpired: false,
94+
trustedRoots: info.roots,
95+
rejectExpired: false,
9696
}
9797

9898
hOpts := HandlerOptions{

0 commit comments

Comments
 (0)