Skip to content

Commit

Permalink
added functionality for scanning subjects
Browse files Browse the repository at this point in the history
Signed-off-by: linus-sun <[email protected]>
  • Loading branch information
linus-sun committed Oct 30, 2024
1 parent b3b5cb9 commit 005c754
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 75 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/go-openapi/swag v0.23.0
github.com/google/certificate-transparency-go v1.2.1
github.com/google/go-github/v65 v65.0.0
github.com/google/trillian v1.6.0
github.com/mailgun/mailgun-go/v4 v4.17.0
github.com/migueleliasweb/go-github-mock v1.1.0
github.com/mocktools/go-smtp-mock/v2 v2.3.1
Expand Down Expand Up @@ -109,10 +110,10 @@ require (
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect
google.golang.org/grpc v1.64.1 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d h1:zjqpY4C7H15HjRPEenkS4SAn3Jy2eRRjkjZbGR30TOg=
github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d/go.mod h1:XNqJ7hv2kY++g8XEHREpi+JqZo3+0l+CH2egBVN4yqM=
github.com/ahmetb/go-linq v3.0.0+incompatible h1:qQkjjOXKrKOTy83X8OpRmnKflXKQIL/mC/gMVVDMhOA=
Expand Down Expand Up @@ -76,10 +78,14 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/certificate-transparency-go v1.2.1 h1:4iW/NwzqOqYEEoCBEFP+jPbBXbLqMpq3CifMyOnDUME=
github.com/google/certificate-transparency-go v1.2.1/go.mod h1:bvn/ytAccv+I6+DGkqpvSsEdiVGramgaSC6RD3tEmeE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
Expand Down Expand Up @@ -137,6 +143,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ=
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailgun/errors v0.3.0 h1:g8R8lodkwqk5WIVMAClyUqt0PSd5JTVgobB+H7C2sLs=
Expand Down Expand Up @@ -343,6 +351,9 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s=
google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7/go.mod h1:/3XmxOjePkvmKrHuBy4zNFw7IzxJXtAgdpXi8Ll990U=
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ=
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 h1:Q2RxlXqh1cgzzUgV261vBO2jI5R/3DD1J2pM0nI4NhU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA=
Expand Down
File renamed without changes.
33 changes: 0 additions & 33 deletions pkg/ct/verifier_test.go → pkg/ct/consistency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ package ct

import (
"encoding/base64"
"fmt"
"net/http"
"net/http/httptest"
"os"
"testing"

Expand All @@ -30,37 +28,6 @@ import (
ctclient "github.com/google/certificate-transparency-go/client"
)

const (
ValidSTHResponseTreeSize = 3721782
ValidSTHResponseTimestamp uint64 = 1396609800587
ValidSTHResponseSHA256RootHash = "SxKOxksguvHPyUaKYKXoZHzXl91Q257+JQ0AUMlFfeo="
ValidSTHResponseTreeHeadSignature = "BAMARjBEAiBUYO2tODlUUw4oWGiVPUHqZadRRyXs9T2rSXchA79VsQIgLASkQv3cu4XdPFCZbgFkIUefniNPCpO3LzzHX53l+wg="
GetSTHConsistencyEmptyResp = `{ "consistency": [ ] }`
)

// serveHandlerAt returns a test HTTP server that only expects requests at the given path, and invokes
// the provided handler for that path.
func serveHandlerAt(t *testing.T, path string, handler func(http.ResponseWriter, *http.Request)) *httptest.Server {
t.Helper()
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == path {
handler(w, r)
} else {
t.Fatalf("Incorrect URL path: %s", r.URL.Path)
}
}))
}

// serveRspAt returns a test HTTP server that returns a canned response body rsp for a given path.
func serveRspAt(t *testing.T, path, rsp string) *httptest.Server {
t.Helper()
return serveHandlerAt(t, path, func(w http.ResponseWriter, _ *http.Request) {
if _, err := fmt.Fprint(w, rsp); err != nil {
t.Fatal(err)
}
})
}

// Test VerifyCertificateTransparencyConsistency
func TestVerifyCertificateTransparencyConsistency(t *testing.T) {
// TODO: placeholder test, fill this out with mock CT Log client
Expand Down
53 changes: 53 additions & 0 deletions pkg/ct/monitor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2024 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ct

import (
"context"
"fmt"
"regexp"

ct "github.com/google/certificate-transparency-go"
ctclient "github.com/google/certificate-transparency-go/client"
"github.com/sigstore/rekor-monitor/pkg/identity"
)

func GetCTLogEntries(logClient *ctclient.LogClient, startIndex int, endIndex int) ([]ct.LogEntry, error) {
entries, err := logClient.GetEntries(context.Background(), int64(startIndex), int64(endIndex))
if err != nil {
return nil, fmt.Errorf("error retrieving certificate transparency log entries: %v", err)
}
return entries, nil
}

func ScanEntrySubject(logEntry ct.LogEntry, monitoredSubjects []string) ([]*identity.LogEntry, error) {
subject := logEntry.X509Cert.Subject.String()
foundEntries := []*identity.LogEntry{}
for _, monitoredSub := range monitoredSubjects {
regex, err := regexp.Compile(monitoredSub)
if err != nil {
return nil, fmt.Errorf("error compiling regex: %v", err)
}
matches := regex.FindAllString(subject, -1)
for _, match := range matches {
foundEntries = append(foundEntries, &identity.LogEntry{
Index: logEntry.Index,
Subject: match,
})
}
}

return foundEntries, nil
}
121 changes: 121 additions & 0 deletions pkg/ct/monitor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright 2024 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ct

import (
"fmt"
"net/http"
"reflect"
"regexp"
"testing"

ct "github.com/google/certificate-transparency-go"
ctclient "github.com/google/certificate-transparency-go/client"
"github.com/google/certificate-transparency-go/jsonclient"
"github.com/google/certificate-transparency-go/x509"
"github.com/google/certificate-transparency-go/x509/pkix"
"github.com/sigstore/rekor-monitor/pkg/identity"
)

const (
subjectName = "test-subject"
organizationName = "test-org"
)

func TestGetCTLogEntries(t *testing.T) {
// TODO: placeholder test- a e2e test of certificate transparency identity monitoring should thoroughly test fetching CT log entries
ts := serverHandlerAt(t, "/ct/v1/get-entries", func(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
numRE := regexp.MustCompile("[0-9]+")
if !numRE.MatchString(q["start"][0]) || !numRE.MatchString(q["end"][0]) {
t.Fatalf("Invalid parameter: start=%q, end=%q", q["start"][0], q["end"][0])
}
_, err := fmt.Fprintf(w, `{"entries":[{"leaf_input": "%s","extra_data": "%s"},{"leaf_input": "%s","extra_data": "%s"}]}`,
PrecertEntryB64,
PrecertEntryExtraDataB64,
CertEntryB64,
CertEntryExtraDataB64)
if err != nil {
t.Fatal(err)
}
})
defer ts.Close()
lc, err := ctclient.New(ts.URL, &http.Client{}, jsonclient.Options{})
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
leaves, err := GetCTLogEntries(lc, 0, 1)
if err != nil {
t.Errorf("GetEntries(0,1)=nil,%v; want 2 leaves,nil", err)
} else if len(leaves) != 2 {
t.Errorf("GetEntries(0,1)=%d leaves,nil; want 2 leaves,nil", len(leaves))
}
}

func TestScanEntrySubject(t *testing.T) {
testCases := map[string]struct {
inputEntry ct.LogEntry
inputSubjects []string
expected []*identity.LogEntry
}{
"no matching subject": {
inputEntry: ct.LogEntry{
Index: 1,
X509Cert: &x509.Certificate{
Subject: pkix.Name{
CommonName: subjectName,
},
},
},
inputSubjects: []string{},
expected: []*identity.LogEntry{},
},
"matching subject": {
inputEntry: ct.LogEntry{
Index: 1,
X509Cert: &x509.Certificate{
Subject: pkix.Name{
CommonName: subjectName,
Organization: []string{organizationName},
},
},
},
inputSubjects: []string{subjectName, organizationName},
expected: []*identity.LogEntry{
{Index: 1,
Subject: subjectName},
{Index: 1,
Subject: organizationName},
},
},
}

for _, tc := range testCases {
logEntries, err := ScanEntrySubject(tc.inputEntry, tc.inputSubjects)
if err != nil {
t.Errorf("received error scanning entry for subjects: %v", err)
}
expected := tc.expected
if logEntries == nil {
if expected != nil {
t.Errorf("received nil, expected log entry")
}
} else {
if !reflect.DeepEqual(logEntries, expected) {
t.Errorf("expected %v, received %v", expected, logEntries)
}
}
}
}
Loading

0 comments on commit 005c754

Please sign in to comment.