Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Update chromepolicy.go to follow the updated Chrome CT Policy" #1154

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
### Add support for IBM Z operating system z/OS
* Add build tags for zos

### Chrome CT Policy Update
* #906: Update chromepolicy.go to follow the updated Chrome CT policy.

### LogList
* Add support for "is_all_logs" field

Expand Down
44 changes: 22 additions & 22 deletions ctpolicy/chromepolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,10 @@
package ctpolicy

import (
"time"

"github.com/google/certificate-transparency-go/loglist3"
"github.com/google/certificate-transparency-go/x509"
)

const (
minOperators = 2 // minimum number of distinct CT log operators that issue an SCT.
dayDuration = 86400 * time.Second // time.Duration of one day
)

// ChromeCTPolicy implements logic for complying with Chrome's CT log policy
type ChromeCTPolicy struct {
}
Expand All @@ -34,30 +27,37 @@ type ChromeCTPolicy struct {
// https://github.com/chromium/ct-policy/blob/master/ct_policy.md#qualifying-certificate.
// Returns an error if it's not possible to satisfy the policy with the provided loglist.
func (chromeP ChromeCTPolicy) LogsByGroup(cert *x509.Certificate, approved *loglist3.LogList) (LogPolicyData, error) {
groups := LogPolicyData{}
for _, op := range approved.Operators {
info := &LogGroupInfo{Name: op.Name, IsBase: false}
info.LogURLs = make(map[string]bool)
info.LogWeights = make(map[string]float32)
for _, l := range op.Logs {
info.LogURLs[l.URL] = true
info.LogWeights[l.URL] = 1.0
}
groups[info.Name] = info
googGroup := LogGroupInfo{Name: "Google-operated", IsBase: false}
googGroup.populate(approved, func(op *loglist3.Operator) bool { return op.GoogleOperated() })
if err := googGroup.setMinInclusions(1); err != nil {
return nil, err
}

nonGoogGroup := LogGroupInfo{Name: "Non-Google-operated", IsBase: false}
nonGoogGroup.populate(approved, func(op *loglist3.Operator) bool { return !op.GoogleOperated() })
if err := nonGoogGroup.setMinInclusions(1); err != nil {
return nil, err
}
var incCount int
switch t := certLifetime(cert); {
case t <= 180*dayDuration:
switch m := lifetimeInMonths(cert); {
case m < 15:
incCount = 2
default:
case m <= 27:
incCount = 3
case m <= 39:
incCount = 4
default:
incCount = 5
}
baseGroup, err := BaseGroupFor(approved, incCount)
if err != nil {
return nil, err
}
baseGroup.MinOperators = minOperators
groups[baseGroup.Name] = baseGroup
groups := LogPolicyData{
googGroup.Name: &googGroup,
nonGoogGroup.Name: &nonGoogGroup,
baseGroup.Name: baseGroup,
}
return groups, nil
}

Expand Down
87 changes: 71 additions & 16 deletions ctpolicy/chromepolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,19 @@ import (
"github.com/kylelemons/godebug/pretty"
)

func wantedGroups(base int, minusBob bool) LogPolicyData {
func wantedGroups(goog int, nonGoog int, base int, minusBob bool) LogPolicyData {
gi := LogPolicyData{
"Google": {
Name: "Google",
"Google-operated": {
Name: "Google-operated",
LogURLs: map[string]bool{
"https://ct.googleapis.com/logs/argon2020/": true,
"https://ct.googleapis.com/aviator/": true,
"https://ct.googleapis.com/icarus/": true,
"https://ct.googleapis.com/rocketeer/": true,
"https://ct.googleapis.com/racketeer/": true,
},
IsBase: false,
MinInclusions: goog,
IsBase: false,
LogWeights: map[string]float32{
"https://ct.googleapis.com/logs/argon2020/": 1.0,
"https://ct.googleapis.com/aviator/": 1.0,
Expand All @@ -41,12 +42,13 @@ func wantedGroups(base int, minusBob bool) LogPolicyData {
"https://ct.googleapis.com/racketeer/": 1.0,
},
},
"Bob's CT Log Shop": {
Name: "Bob's CT Log Shop",
"Non-Google-operated": {
Name: "Non-Google-operated",
LogURLs: map[string]bool{
"https://log.bob.io": true,
},
IsBase: false,
MinInclusions: nonGoog,
IsBase: false,
LogWeights: map[string]float32{
"https://log.bob.io": 1.0,
},
Expand All @@ -62,7 +64,6 @@ func wantedGroups(base int, minusBob bool) LogPolicyData {
"https://log.bob.io": true,
},
MinInclusions: base,
MinOperators: minOperators,
IsBase: true,
LogWeights: map[string]float32{
"https://ct.googleapis.com/logs/argon2020/": 1.0,
Expand All @@ -77,12 +78,11 @@ func wantedGroups(base int, minusBob bool) LogPolicyData {
if minusBob {
delete(gi[BaseName].LogURLs, "https://log.bob.io")
delete(gi[BaseName].LogWeights, "https://log.bob.io")
delete(gi["Bob's CT Log Shop"].LogURLs, "https://log.bob.io")
delete(gi["Bob's CT Log Shop"].LogWeights, "https://log.bob.io")
delete(gi["Non-Google-operated"].LogURLs, "https://log.bob.io")
delete(gi["Non-Google-operated"].LogWeights, "https://log.bob.io")
}
return gi
}

func TestCheckChromePolicy(t *testing.T) {
tests := []struct {
name string
Expand All @@ -92,28 +92,27 @@ func TestCheckChromePolicy(t *testing.T) {
{
name: "Short",
cert: getTestCertPEMShort(),
want: wantedGroups(2, false),
want: wantedGroups(1, 1, 2, false),
},
{
name: "2-year",
cert: getTestCertPEM2Years(),
want: wantedGroups(3, false),
want: wantedGroups(1, 1, 3, false),
},
{
name: "3-year",
cert: getTestCertPEM3Years(),
want: wantedGroups(3, false),
want: wantedGroups(1, 1, 4, false),
},
{
name: "Long",
cert: getTestCertPEMLongOriginal(),
want: wantedGroups(3, false),
want: wantedGroups(1, 1, 5, false),
},
}

var policy ChromeCTPolicy
sampleLogList := sampleLogList(t)

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := policy.LogsByGroup(test.cert, sampleLogList)
Expand All @@ -126,3 +125,59 @@ func TestCheckChromePolicy(t *testing.T) {
})
}
}

func TestCheckChromePolicyWarnings(t *testing.T) {
tests := []struct {
name string
cert *x509.Certificate
want LogPolicyData
warning string
}{
{
name: "Short",
cert: getTestCertPEMShort(),
want: LogPolicyData{},
warning: "trying to assign 1 minimal inclusion number while only 0 logs are part of group \"Non-Google-operated\"",
},
{
name: "2-year",
cert: getTestCertPEM2Years(),
want: LogPolicyData{},
warning: "trying to assign 1 minimal inclusion number while only 0 logs are part of group \"Non-Google-operated\"",
},
{
name: "3-year",
cert: getTestCertPEM3Years(),
want: LogPolicyData{},
warning: "trying to assign 1 minimal inclusion number while only 0 logs are part of group \"Non-Google-operated\"",
},
{
name: "Long",
cert: getTestCertPEMLongOriginal(),
want: LogPolicyData{},
warning: "trying to assign 1 minimal inclusion number while only 0 logs are part of group \"Non-Google-operated\"",
},
}

var policy ChromeCTPolicy
sampleLogList := sampleLogList(t)
// Removing Bob-log.
sampleLogList.Operators = sampleLogList.Operators[:1]

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {

got, err := policy.LogsByGroup(test.cert, sampleLogList)
if diff := pretty.Compare(test.want, got); diff != "" {
t.Errorf("LogsByGroup: (-want +got)\n%s", diff)
}
if err == nil && len(test.warning) > 0 {
t.Errorf("LogsByGroup returned no error when expected")
} else if err != nil {
if err.Error() != test.warning {
t.Errorf("LogsByGroup returned error message %q while expected %q", err.Error(), test.warning)
}
}
})
}
}
9 changes: 0 additions & 9 deletions ctpolicy/ctpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package ctpolicy
import (
"fmt"
"sync"
"time"

"github.com/google/certificate-transparency-go/loglist3"
"github.com/google/certificate-transparency-go/x509"
Expand All @@ -34,7 +33,6 @@ type LogGroupInfo struct {
Name string
LogURLs map[string]bool // set of members
MinInclusions int // Required number of submissions.
MinOperators int // Required number of distinct CT log operators.
IsBase bool // True only for Log-group covering all logs.
LogWeights map[string]float32 // weights used for submission, default weight is 1
wMu sync.RWMutex // guards weights
Expand Down Expand Up @@ -207,13 +205,6 @@ func lifetimeInMonths(cert *x509.Certificate) int {
return lifetimeInMonths
}

// certLifetime calculates and returns the lifetime of the given certificate as a time.Duration
func certLifetime(cert *x509.Certificate) time.Duration {
start := cert.NotBefore
end := cert.NotAfter
return end.Sub(start)
}

// GroupSet is set of Log-group names.
type GroupSet map[string]bool

Expand Down
48 changes: 1 addition & 47 deletions ctpolicy/ctpolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

func getTestCertPEMShort() *x509.Certificate {
cert, _ := x509util.CertificateFromPEM([]byte(testdata.TestCertPEM))
cert.NotAfter = time.Date(2012, 6, 1, 0, 0, 0, 0, time.UTC)
cert.NotAfter = time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)
return cert
}

Expand Down Expand Up @@ -104,52 +104,6 @@ func TestLifetimeInMonths(t *testing.T) {
}
}

func TestCertLifetime(t *testing.T) {
tests := []struct {
name string
notBefore time.Time
notAfter time.Time
want time.Duration
}{
{
name: "ExactDays",
notBefore: time.Date(2012, 6, 1, 0, 0, 0, 0, time.UTC),
notAfter: time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC),
want: 18489600 * time.Second,
},
{
name: "ExactYears",
notBefore: time.Date(2012, 6, 1, 0, 0, 0, 0, time.UTC),
notAfter: time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC),
want: 81561600 * time.Second,
},
{
name: "PartialSingleDay",
notBefore: time.Date(2012, 6, 1, 0, 0, 0, 0, time.UTC),
notAfter: time.Date(2012, 6, 1, 15, 0, 0, 0, time.UTC),
want: 54000 * time.Second,
},
{
name: "PartialDays",
notBefore: time.Date(2012, 6, 25, 0, 0, 0, 0, time.UTC),
notAfter: time.Date(2012, 6, 30, 12, 0, 0, 0, time.UTC),
want: 475200 * time.Second,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cert := getTestCertPEMLongOriginal()
cert.NotBefore = test.notBefore
cert.NotAfter = test.notAfter
got := certLifetime(cert)
if got != test.want {
t.Errorf("certLifetime(%v, %v)=%d, want %d", test.notBefore, test.notAfter, got, test.want)
}
})
}
}

func TestGroupByLogs(t *testing.T) {
tests := []struct {
name string
Expand Down
12 changes: 1 addition & 11 deletions submission/races.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ type groupState struct {
type safeSubmissionState struct {
mu sync.Mutex
logToGroups map[string]ctpolicy.GroupSet
groupNeeds map[string]int // number of logs that need to be submitted for each group.
minGroups int // minimum number of distinct groups that need a log submitted.
groupNeeds map[string]int

groups map[string]bool // set of groups that have a log submitted.
results map[string]*submissionResult
cancels map[string]context.CancelFunc
}
Expand All @@ -69,10 +67,6 @@ func newSafeSubmissionState(groups ctpolicy.LogPolicyData) *safeSubmissionState
for _, g := range groups {
s.groupNeeds[g.Name] = g.MinInclusions
}
if baseGroup, ok := groups[ctpolicy.BaseName]; ok {
s.minGroups = baseGroup.MinOperators
}
s.groups = make(map[string]bool)
s.results = make(map[string]*submissionResult)
s.cancels = make(map[string]context.CancelFunc)
return &s
Expand Down Expand Up @@ -122,7 +116,6 @@ func (sub *safeSubmissionState) setResult(logURL string, sct *ct.SignedCertifica
if sub.groupNeeds[groupName] > 0 {
sub.results[logURL] = &submissionResult{sct: sct, err: err}
}
sub.groups[groupName] = true
sub.groupNeeds[groupName]--
}

Expand Down Expand Up @@ -172,9 +165,6 @@ func (sub *safeSubmissionState) groupComplete(groupName string) bool {
if !ok {
return true
}
if len(sub.groups) < sub.minGroups {
return false
}
return needs <= 0
}

Expand Down
Loading