From 33eacc86ef33c3f4cdfae51616cef679d2d48e37 Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Wed, 4 Sep 2024 00:21:10 -0700 Subject: [PATCH 1/8] started as just filepath.Join(target.Path, name) in writeLocalFile Then noticed we were modifying http.Client live in the process --- signer/contentsignaturepki/upload.go | 65 ++++++++++++++++------------ 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/signer/contentsignaturepki/upload.go b/signer/contentsignaturepki/upload.go index 1e54a859e..2c2f75f7e 100644 --- a/signer/contentsignaturepki/upload.go +++ b/signer/contentsignaturepki/upload.go @@ -10,6 +10,7 @@ import ( "net/url" "os" "path" + "path/filepath" "strings" "time" @@ -19,6 +20,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" csigverifier "github.com/mozilla-services/autograph/verifier/contentsignature" + log "github.com/sirupsen/logrus" ) // S3UploadAPI is an interface to accommodate testing @@ -82,8 +84,9 @@ func writeLocalFile(data, name string, target *url.URL) error { return err } } - // write the file into the target dir - return os.WriteFile(target.Path+name, []byte(data), 0755) + + log.Printf("FIXME writing to %s", filepath.Join(target.Path, name)) + return os.WriteFile(filepath.Join(target.Path, name), []byte(data), 0755) } // buildHTTPClient returns the default HTTP.Client for fetching X5Us @@ -94,44 +97,50 @@ func buildHTTPClient() *http.Client { // GetX5U retrieves a chain file of certs from upload location, parses // and verifies it, then returns a byte slice of the response body and // a slice of parsed certificates. -func GetX5U(client *http.Client, x5u string) (body []byte, certs []*x509.Certificate, err error) { +func GetX5U(client *http.Client, x5u string) ([]byte, []*x509.Certificate, error) { parsedURL, err := url.Parse(x5u) if err != nil { - err = fmt.Errorf("failed to parse chain upload location: %w", err) - return - } - if parsedURL.Scheme == "file" { - t := &http.Transport{} - t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) - client.Transport = t - } - resp, err := client.Get(x5u) - if err != nil { - err = fmt.Errorf("failed to retrieve x5u: %w", err) - return + return nil, nil, fmt.Errorf("failed to parse chain upload location: %w", err) + } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - err = fmt.Errorf("failed to retrieve x5u from %s: %s", x5u, resp.Status) - return + var bodyReader io.ReadCloser + switch parsedURL.Scheme { + case "https": + resp, err := client.Get(x5u) + if err != nil { + return nil, nil, fmt.Errorf("failed to retrieve x5u from %#v: %w", x5u, err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, nil, fmt.Errorf("failed to retrieve x5u from %#v: %s", x5u, resp.Status) + } + bodyReader = resp.Body + + case "file": + bodyReader, err = os.Open(parsedURL.Path) + if err != nil { + return nil, nil, fmt.Errorf("failed to open x5u file:// at %#v: %w", x5u, err) + } + defer bodyReader.Close() + default: + return nil, nil, fmt.Errorf("unsupported x5u scheme: %#v", parsedURL.Scheme) } - body, err = io.ReadAll(resp.Body) + + body, err := io.ReadAll(bodyReader) if err != nil { - err = fmt.Errorf("failed to parse x5u body: %w", err) - return + return nil, nil, fmt.Errorf("failed to parse x5u body from %#v: %w", x5u, err) } - certs, err = csigverifier.ParseChain(body) + certs, err := csigverifier.ParseChain(body) if err != nil { - err = fmt.Errorf("failed to parse x5u : %w", err) - return + + return nil, nil, fmt.Errorf("failed to parse x5u : %w", err) } rootHash := sha2Fingerprint(certs[2]) err = csigverifier.VerifyChain([]string{rootHash}, certs, time.Now()) if err != nil { - err = fmt.Errorf("failed to verify certificate chain: %w", err) - return + return nil, nil, fmt.Errorf("failed to verify certificate chain: %w", err) } - return + return body, certs, nil } func sha2Fingerprint(cert *x509.Certificate) string { From bc1e9f1d8d141a2da6018fa70da14a474ff29e4c Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Wed, 4 Sep 2024 00:25:20 -0700 Subject: [PATCH 2/8] make subtests for easier testing --- .../contentsignature_test.go | 125 +++++++++--------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/signer/contentsignaturepki/contentsignature_test.go b/signer/contentsignaturepki/contentsignature_test.go index b196b122f..48f755db0 100644 --- a/signer/contentsignaturepki/contentsignature_test.go +++ b/signer/contentsignaturepki/contentsignature_test.go @@ -9,6 +9,7 @@ package contentsignaturepki import ( "crypto/ecdsa" "errors" + "fmt" "strings" "testing" @@ -19,73 +20,75 @@ import ( func TestSign(t *testing.T) { input := []byte("foobarbaz1234abcd") for i, testcase := range PASSINGTESTCASES { - // initialize a signer - s, err := New(testcase.cfg) - if err != nil { - t.Fatalf("testcase %d signer initialization failed with: %v", i, err) - } - if s.Type != testcase.cfg.Type { - t.Fatalf("testcase %d signer type %q does not match configuration %q", i, s.Type, testcase.cfg.Type) - } - if s.ID != testcase.cfg.ID { - t.Fatalf("testcase %d signer id %q does not match configuration %q", i, s.ID, testcase.cfg.ID) - } - if s.PrivateKey != testcase.cfg.PrivateKey { - t.Fatalf("testcase %d signer private key %q does not match configuration %q", i, s.PrivateKey, testcase.cfg.PrivateKey) - } - if s.Mode != testcase.cfg.Mode { - t.Fatalf("testcase %d signer curve %q does not match expected %q", i, s.Mode, testcase.cfg.Mode) - } + t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) { + // initialize a signer + s, err := New(testcase.cfg) + if err != nil { + t.Fatalf("testcase %d signer initialization failed with: %v", i, err) + } + if s.Type != testcase.cfg.Type { + t.Fatalf("testcase %d signer type %q does not match configuration %q", i, s.Type, testcase.cfg.Type) + } + if s.ID != testcase.cfg.ID { + t.Fatalf("testcase %d signer id %q does not match configuration %q", i, s.ID, testcase.cfg.ID) + } + if s.PrivateKey != testcase.cfg.PrivateKey { + t.Fatalf("testcase %d signer private key %q does not match configuration %q", i, s.PrivateKey, testcase.cfg.PrivateKey) + } + if s.Mode != testcase.cfg.Mode { + t.Fatalf("testcase %d signer curve %q does not match expected %q", i, s.Mode, testcase.cfg.Mode) + } - // sign input data - sig, err := s.SignData(input, nil) - if err != nil { - t.Fatalf("testcase %d failed to sign data: %v", i, err) - } - // convert signature to string format - sigstr, err := sig.Marshal() - if err != nil { - t.Fatalf("testcase %d failed to marshal signature: %v", i, err) - } + // sign input data + sig, err := s.SignData(input, nil) + if err != nil { + t.Fatalf("testcase %d failed to sign data: %v", i, err) + } + // convert signature to string format + sigstr, err := sig.Marshal() + if err != nil { + t.Fatalf("testcase %d failed to marshal signature: %v", i, err) + } - // convert string format back to signature - cs, err := verifier.Unmarshal(sigstr) - if err != nil { - t.Fatalf("testcase %d failed to unmarshal signature: %v", i, err) - } + // convert string format back to signature + cs, err := verifier.Unmarshal(sigstr) + if err != nil { + t.Fatalf("testcase %d failed to unmarshal signature: %v", i, err) + } - // make sure we still have the same string representation - sigstr2, err := cs.Marshal() - if err != nil { - t.Fatalf("testcase %d failed to re-marshal signature: %v", i, err) - } - if sigstr != sigstr2 { - t.Fatalf("testcase %d marshalling signature changed its format.\nexpected\t%q\nreceived\t%q", - i, sigstr, sigstr2) - } + // make sure we still have the same string representation + sigstr2, err := cs.Marshal() + if err != nil { + t.Fatalf("testcase %d failed to re-marshal signature: %v", i, err) + } + if sigstr != sigstr2 { + t.Fatalf("testcase %d marshalling signature changed its format.\nexpected\t%q\nreceived\t%q", + i, sigstr, sigstr2) + } - if cs.Len != getSignatureLen(s.Mode) { - t.Fatalf("testcase %d expected signature len of %d, got %d", - i, getSignatureLen(s.Mode), cs.Len) - } - if cs.Mode != s.Mode { - t.Fatalf("testcase %d expected curve name %q, got %q", i, s.Mode, cs.Mode) - } + if cs.Len != getSignatureLen(s.Mode) { + t.Fatalf("testcase %d expected signature len of %d, got %d", + i, getSignatureLen(s.Mode), cs.Len) + } + if cs.Mode != s.Mode { + t.Fatalf("testcase %d expected curve name %q, got %q", i, s.Mode, cs.Mode) + } - // verify the signature using the public key of the end entity - _, certs, err := GetX5U(buildHTTPClient(), s.X5U) - if err != nil { - t.Fatalf("testcase %d failed to get X5U %q: %v", i, s.X5U, err) - } - leaf := certs[0] - key := leaf.PublicKey.(*ecdsa.PublicKey) - if !sig.(*verifier.ContentSignature).VerifyData([]byte(input), key) { - t.Fatalf("testcase %d failed to verify signature", i) - } + // verify the signature using the public key of the end entity + _, certs, err := GetX5U(buildHTTPClient(), s.X5U) + if err != nil { + t.Fatalf("testcase %d failed to get X5U %q: %v", i, s.X5U, err) + } + leaf := certs[0] + key := leaf.PublicKey.(*ecdsa.PublicKey) + if !sig.(*verifier.ContentSignature).VerifyData([]byte(input), key) { + t.Fatalf("testcase %d failed to verify signature", i) + } - if leaf.Subject.CommonName != testcase.expectedCommonName { - t.Errorf("testcase %d expected common name %#v, got %#v", i, testcase.expectedCommonName, leaf.Subject.CommonName) - } + if leaf.Subject.CommonName != testcase.expectedCommonName { + t.Errorf("testcase %d expected common name %#v, got %#v", i, testcase.expectedCommonName, leaf.Subject.CommonName) + } + }) } } From 02b1a0cb3492d1ee22da661abf1914594f77293e Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Wed, 4 Sep 2024 00:33:50 -0700 Subject: [PATCH 3/8] join the X5U --- signer/contentsignaturepki/x509.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/signer/contentsignaturepki/x509.go b/signer/contentsignaturepki/x509.go index 894d60f8d..cb084a908 100644 --- a/signer/contentsignaturepki/x509.go +++ b/signer/contentsignaturepki/x509.go @@ -7,6 +7,7 @@ import ( "encoding/pem" "fmt" "math/big" + "path" "time" "github.com/mozilla-services/autograph/database" @@ -51,7 +52,7 @@ func (s *ContentSigner) makeAndUploadChain() (err error) { if err != nil { return fmt.Errorf("failed to upload chain: %w", err) } - newX5U := s.X5U + chainName + newX5U := path.Join(s.X5U, chainName) _, _, err = GetX5U(buildHTTPClient(), newX5U) if err != nil { return fmt.Errorf("failed to download new chain: %w", err) From 7f043b13fef0617ca7b85863767713135c6d73f0 Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Wed, 4 Sep 2024 00:36:04 -0700 Subject: [PATCH 4/8] remove FIXME log --- signer/contentsignaturepki/upload.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/signer/contentsignaturepki/upload.go b/signer/contentsignaturepki/upload.go index 2c2f75f7e..b739a7cb5 100644 --- a/signer/contentsignaturepki/upload.go +++ b/signer/contentsignaturepki/upload.go @@ -20,7 +20,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" csigverifier "github.com/mozilla-services/autograph/verifier/contentsignature" - log "github.com/sirupsen/logrus" ) // S3UploadAPI is an interface to accommodate testing @@ -85,7 +84,6 @@ func writeLocalFile(data, name string, target *url.URL) error { } } - log.Printf("FIXME writing to %s", filepath.Join(target.Path, name)) return os.WriteFile(filepath.Join(target.Path, name), []byte(data), 0755) } From c11aba55f08493d36fa298ed37c01427976333c6 Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Wed, 4 Sep 2024 00:36:28 -0700 Subject: [PATCH 5/8] use url.JoinPath to correctly escape and join x5u and chainName --- signer/contentsignaturepki/x509.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/signer/contentsignaturepki/x509.go b/signer/contentsignaturepki/x509.go index cb084a908..9b47b3d36 100644 --- a/signer/contentsignaturepki/x509.go +++ b/signer/contentsignaturepki/x509.go @@ -7,7 +7,7 @@ import ( "encoding/pem" "fmt" "math/big" - "path" + "net/url" "time" "github.com/mozilla-services/autograph/database" @@ -42,9 +42,8 @@ func (s *ContentSigner) findAndSetEE(conf signer.Configuration) (err error) { // makeAndUploadChain makes a certificate using the end-entity public key, // uploads the chain to its destination and creates an X5U download URL -func (s *ContentSigner) makeAndUploadChain() (err error) { - var fullChain, chainName string - fullChain, chainName, err = s.makeChain() +func (s *ContentSigner) makeAndUploadChain() error { + fullChain, chainName, err := s.makeChain() if err != nil { return fmt.Errorf("failed to make chain: %w", err) } @@ -52,13 +51,16 @@ func (s *ContentSigner) makeAndUploadChain() (err error) { if err != nil { return fmt.Errorf("failed to upload chain: %w", err) } - newX5U := path.Join(s.X5U, chainName) + newX5U, err := url.JoinPath(s.X5U, chainName) + if err != nil { + return fmt.Errorf("failed to join x5u with chain name: %w", err) + } _, _, err = GetX5U(buildHTTPClient(), newX5U) if err != nil { return fmt.Errorf("failed to download new chain: %w", err) } s.X5U = newX5U - return + return nil } // makeChain issues an end-entity certificate using the ca private key and the first From f2b2d98bfdcfef27578f456ecedac884f3deeb5f Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Wed, 4 Sep 2024 00:38:57 -0700 Subject: [PATCH 6/8] use default http client everywhere now since we're not modifying it Need a test that ensures we're using url.JoinPath or equivalent when adding the chain name to the X5U endpoint URL. --- signer/contentsignaturepki/contentsignature.go | 3 ++- signer/contentsignaturepki/contentsignature_test.go | 3 ++- signer/contentsignaturepki/upload.go | 5 ----- signer/contentsignaturepki/x509.go | 3 ++- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/signer/contentsignaturepki/contentsignature.go b/signer/contentsignaturepki/contentsignature.go index e8bfbd546..093e9c318 100644 --- a/signer/contentsignaturepki/contentsignature.go +++ b/signer/contentsignaturepki/contentsignature.go @@ -10,6 +10,7 @@ import ( "hash" "io" "math/big" + "net/http" "time" "github.com/mozilla-services/autograph/database" @@ -185,7 +186,7 @@ func (s *ContentSigner) initEE(conf signer.Configuration) error { default: return fmt.Errorf("contentsignaturepki %q: failed to find suitable end-entity: %w", s.ID, err) } - _, _, err = GetX5U(buildHTTPClient(), s.X5U) + _, _, err = GetX5U(http.DefaultClient, s.X5U) if err != nil { return fmt.Errorf("contentsignaturepki %q: failed to verify x5u: %w", s.ID, err) } diff --git a/signer/contentsignaturepki/contentsignature_test.go b/signer/contentsignaturepki/contentsignature_test.go index 48f755db0..cd0539e7e 100644 --- a/signer/contentsignaturepki/contentsignature_test.go +++ b/signer/contentsignaturepki/contentsignature_test.go @@ -10,6 +10,7 @@ import ( "crypto/ecdsa" "errors" "fmt" + "net/http" "strings" "testing" @@ -75,7 +76,7 @@ func TestSign(t *testing.T) { } // verify the signature using the public key of the end entity - _, certs, err := GetX5U(buildHTTPClient(), s.X5U) + _, certs, err := GetX5U(http.DefaultClient, s.X5U) if err != nil { t.Fatalf("testcase %d failed to get X5U %q: %v", i, s.X5U, err) } diff --git a/signer/contentsignaturepki/upload.go b/signer/contentsignaturepki/upload.go index b739a7cb5..758c1fdb5 100644 --- a/signer/contentsignaturepki/upload.go +++ b/signer/contentsignaturepki/upload.go @@ -87,11 +87,6 @@ func writeLocalFile(data, name string, target *url.URL) error { return os.WriteFile(filepath.Join(target.Path, name), []byte(data), 0755) } -// buildHTTPClient returns the default HTTP.Client for fetching X5Us -func buildHTTPClient() *http.Client { - return &http.Client{} -} - // GetX5U retrieves a chain file of certs from upload location, parses // and verifies it, then returns a byte slice of the response body and // a slice of parsed certificates. diff --git a/signer/contentsignaturepki/x509.go b/signer/contentsignaturepki/x509.go index 9b47b3d36..30a32a3e6 100644 --- a/signer/contentsignaturepki/x509.go +++ b/signer/contentsignaturepki/x509.go @@ -7,6 +7,7 @@ import ( "encoding/pem" "fmt" "math/big" + "net/http" "net/url" "time" @@ -55,7 +56,7 @@ func (s *ContentSigner) makeAndUploadChain() error { if err != nil { return fmt.Errorf("failed to join x5u with chain name: %w", err) } - _, _, err = GetX5U(buildHTTPClient(), newX5U) + _, _, err = GetX5U(http.DefaultClient, newX5U) if err != nil { return fmt.Errorf("failed to download new chain: %w", err) } From 48e4e16a1aaddad581391466a14299f1c7725fb9 Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Mon, 21 Oct 2024 14:32:01 -0700 Subject: [PATCH 7/8] tlsserver --- .../contentsignaturepki_test.go | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/autograph-monitor/contentsignaturepki_test.go b/tools/autograph-monitor/contentsignaturepki_test.go index c39d49a19..2bd556bc6 100644 --- a/tools/autograph-monitor/contentsignaturepki_test.go +++ b/tools/autograph-monitor/contentsignaturepki_test.go @@ -167,32 +167,32 @@ func Test_verifyContentSignature(t *testing.T) { })) defer ts.Close() - oneCertChainTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + oneCertChainTestServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, NormandyDevChain2021Intermediate) })) defer oneCertChainTestServer.Close() - rsaLeafChainTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rsaLeafChainTestServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, string(rsaLeafChain)) })) defer rsaLeafChainTestServer.Close() - testLeafChainTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + testLeafChainTestServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, string(testLeafChain)) })) defer testLeafChainTestServer.Close() - testLeafExpiringSoonChainTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + testLeafExpiringSoonChainTestServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, string(mustCertsToChain([]*x509.Certificate{testLeaf7DaysToExpiration, testInter, testRoot}))) })) defer testLeafExpiringSoonChainTestServer.Close() - testInterExpiringSoonChainTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + testInterExpiringSoonChainTestServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, string(mustCertsToChain([]*x509.Certificate{testLeaf, testInter30DaysToExpiration, testRoot}))) })) defer testInterExpiringSoonChainTestServer.Close() - testRootExpiringSoonChainTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + testRootExpiringSoonChainTestServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, string(mustCertsToChain([]*x509.Certificate{testLeaf, testInter, testRoot16DaysToExpiration}))) })) defer testRootExpiringSoonChainTestServer.Close() @@ -220,7 +220,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "valid csig response", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: nil, rootHashes: []string{sha2Fingerprint(testRoot)}, response: formats.SignatureResponse{ @@ -237,7 +237,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "valid csig response typed nil notifier ok", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: typedNilNotifier, rootHashes: []string{sha2Fingerprint(testRoot)}, response: formats.SignatureResponse{ @@ -254,7 +254,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "valid csig response notifies", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: nil, rootHashes: []string{sha2Fingerprint(testRoot)}, response: formats.SignatureResponse{ @@ -279,7 +279,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "valid csig response with invalid root hash but ignored EE ok", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: nil, rootHashes: []string{"invalidroothash"}, ignoredCerts: map[string]bool{"example.content-signature.mozilla.org": true}, @@ -298,7 +298,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "valid csig response with invalid root hash fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: nil, rootHashes: []string{"invalidroothash"}, response: formats.SignatureResponse{ @@ -316,7 +316,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "empty x5u fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: nil, rootHashes: []string{"invalidroothash"}, response: formats.SignatureResponse{ @@ -351,7 +351,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "truncated signature fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: nil, rootHashes: []string{sha2Fingerprint(testRoot)}, response: formats.SignatureResponse{ @@ -369,7 +369,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "one cert X5U chain fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: oneCertChainTestServer.Client(), notifier: nil, rootHashes: normandyDev2021Roothash, response: formats.SignatureResponse{ @@ -388,7 +388,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "bad EE pubkey fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: rsaLeafChainTestServer.Client(), notifier: nil, rootHashes: normandyDev2021Roothash, response: formats.SignatureResponse{ @@ -407,7 +407,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "invalid data (wrong EE for normandyDev2021Roothash) fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafChainTestServer.Client(), notifier: nil, rootHashes: normandyDev2021Roothash, response: formats.SignatureResponse{ @@ -426,7 +426,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "expiring EE fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: testLeafExpiringSoonChainTestServer.Client(), notifier: nil, rootHashes: []string{sha2Fingerprint(testRoot)}, response: formats.SignatureResponse{ @@ -444,7 +444,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "expiring inter fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: testInterExpiringSoonChainTestServer.Client(), notifier: nil, rootHashes: []string{sha2Fingerprint(testRoot)}, response: formats.SignatureResponse{ @@ -462,7 +462,7 @@ func Test_verifyContentSignature(t *testing.T) { { name: "expiring root fails", args: args{ - x5uClient: &http.Client{}, + x5uClient: testRootExpiringSoonChainTestServer.Client(), notifier: nil, rootHashes: []string{sha2Fingerprint(testRoot16DaysToExpiration)}, response: formats.SignatureResponse{ From 2570fd8e5d091e9db35500b3b372ae61fb2b7661 Mon Sep 17 00:00:00 2001 From: Jeff Hodges Date: Tue, 10 Dec 2024 17:55:38 -0800 Subject: [PATCH 8/8] add http to allowed schemes --- signer/contentsignaturepki/upload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signer/contentsignaturepki/upload.go b/signer/contentsignaturepki/upload.go index 758c1fdb5..f444b1070 100644 --- a/signer/contentsignaturepki/upload.go +++ b/signer/contentsignaturepki/upload.go @@ -98,7 +98,7 @@ func GetX5U(client *http.Client, x5u string) ([]byte, []*x509.Certificate, error } var bodyReader io.ReadCloser switch parsedURL.Scheme { - case "https": + case "https", "http": resp, err := client.Get(x5u) if err != nil { return nil, nil, fmt.Errorf("failed to retrieve x5u from %#v: %w", x5u, err)