1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 18:15:42 +01:00

Started with loading provider-metadata.json from a list of possible locations.

This commit is contained in:
Sascha L. Teichmann 2022-02-07 17:37:01 +01:00
parent b0bf18ccdc
commit 27f1aa5461

View file

@ -43,6 +43,7 @@ type processor struct {
redirects map[string]string
noneTLS map[string]struct{}
alreadyChecked map[string]whereType
pmdURL string
pmd256 []byte
pmd interface{}
keys []*crypto.KeyRing
@ -119,6 +120,7 @@ func (p *processor) clean() {
for k := range p.alreadyChecked {
delete(p.alreadyChecked, k)
}
p.pmdURL = ""
p.pmd256 = nil
p.pmd = nil
p.keys = nil
@ -131,6 +133,7 @@ func (p *processor) clean() {
p.badIndices = nil
p.badChanges = nil
}
func (p *processor) run(reporters []reporter, domains []string) (*Report, error) {
var report Report
@ -607,7 +610,7 @@ func (p *processor) checkChanges(base string, mask whereType) error {
func (p *processor) processROLIEFeeds(domain string, feeds [][]csaf.Feed) error {
base, err := url.Parse("https://" + domain + "/.well-known/csaf/")
base, err := url.Parse(p.pmdURL)
if err != nil {
return err
}
@ -654,7 +657,10 @@ func (p *processor) checkCSAFs(domain string) error {
}
// No rolie feeds
base := "https://" + domain + "/.well-known/csaf"
base, err := basePath(p.pmdURL)
if err != nil {
return err
}
if err := p.checkIndex(base, indexMask); err != nil && err != errContinue {
return err
@ -701,36 +707,65 @@ func (p *processor) checkMissing(string) error {
return nil
}
func (p *processor) checkProviderMetadata(domain string) error {
var providerMetadataLocations = [...]string{
".well-known/csaf",
"security/data/csaf",
"advisories/csaf",
"security/csaf",
}
// locateProviderMetadata searches for provider-metadata.json at various
// locations mentioned in "7.1.7 Requirement 7: provider-metadata.json".
func (p *processor) locateProviderMetadata(
domain string,
found func(string, io.Reader) error,
) error {
client := p.httpClient()
url := "https://" + domain + "/.well-known/csaf/provider-metadata.json"
for _, loc := range providerMetadataLocations {
url := "https://" + domain + "/" + loc
res, err := client.Get(url)
if err != nil {
continue
}
if res.StatusCode != http.StatusOK {
continue
}
if res.Header.Get("Content-Type") != "application/json" {
continue
}
if err := func() error {
defer res.Body.Close()
return found(url, res.Body)
}(); err != nil {
if err == errContinue {
continue
}
return err
}
break
}
// TODO: Read from security.txt
return nil
}
func (p *processor) checkProviderMetadata(domain string) error {
use(&p.badProviderMetadatas)
res, err := client.Get(url)
if err != nil {
p.badProviderMetadata("Fetching %s: %v.", url, err)
return errStop
}
if res.StatusCode != http.StatusOK {
p.badProviderMetadata("Fetching %s failed. Status code: %d (%s)",
url, res.StatusCode, res.Status)
return errStop
}
found := func(url string, content io.Reader) error {
// Calculate checksum for later comparison.
hash := sha256.New()
if err := func() error {
defer res.Body.Close()
tee := io.TeeReader(res.Body, hash)
return json.NewDecoder(tee).Decode(&p.pmd)
}(); err != nil {
p.badProviderMetadata("Decoding JSON failed: %v", err)
return errStop
tee := io.TeeReader(content, hash)
if err := json.NewDecoder(tee).Decode(&p.pmd); err != nil {
p.badProviderMetadata("%s: Decoding JSON failed: %v", url, err)
return errContinue
}
p.pmd256 = hash.Sum(nil)
@ -740,10 +775,23 @@ func (p *processor) checkProviderMetadata(domain string) error {
return err
}
if len(errors) > 0 {
p.badProviderMetadata("Validating against JSON schema failed:")
p.badProviderMetadata("%s: Validating against JSON schema failed:", url)
for _, msg := range errors {
p.badProviderMetadata(strings.ReplaceAll(msg, `%`, `%%`))
}
return errStop
}
p.pmdURL = url
return nil
}
if err := p.locateProviderMetadata(domain, found); err != nil {
return err
}
if p.pmdURL == "" {
p.badProviderMetadata("No provider-metadata.json found.")
return errStop
}
return nil
}
@ -851,7 +899,7 @@ func (p *processor) checkPGPKeys(domain string) error {
client := p.httpClient()
base, err := url.Parse("https://" + domain + "/.well-known/csaf/provider-metadata.json")
base, err := url.Parse(p.pmdURL)
if err != nil {
return err
}