Skip to content

Commit

Permalink
Differentiate if fingerprint is empty or not given
Browse files Browse the repository at this point in the history
  • Loading branch information
koplas committed Aug 20, 2024
1 parent 9037574 commit 7b1c350
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 52 deletions.
14 changes: 4 additions & 10 deletions cmd/csaf_aggregator/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ func (w *worker) mirror() (*csaf.AggregatorCSAFProvider, error) {
}

func (w *worker) mirrorInternal() (*csaf.AggregatorCSAFProvider, error) {

// Check if we are allowed to mirror this domain.
if !w.mirrorAllowed() {
return nil, fmt.Errorf(
Expand Down Expand Up @@ -97,7 +96,6 @@ func (w *worker) mirrorInternal() (*csaf.AggregatorCSAFProvider, error) {
}

acp, err := w.createAggregatorProvider()

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -125,7 +123,6 @@ func (w *worker) labelsFromSummaries() []csaf.TLPLabel {

// writeProviderMetadata writes a local provider metadata for a mirror.
func (w *worker) writeProviderMetadata() error {

fname := filepath.Join(w.dir, "provider-metadata.json")

pm := csaf.NewProviderMetadataPrefix(
Expand Down Expand Up @@ -199,7 +196,7 @@ func (w *worker) mirrorPGPKeys(pm *csaf.ProviderMetadata) error {
w.log.Warn("Ignoring PGP key without URL", "fingerprint", pgpKey.Fingerprint)
continue
}
if _, err := hex.DecodeString(string(pgpKey.Fingerprint)); err != nil {
if _, err := hex.DecodeString(string(*pgpKey.Fingerprint)); err != nil {
w.log.Warn("Ignoring PGP key with invalid fingerprint", "url", *pgpKey.URL)
continue
}
Expand All @@ -217,7 +214,7 @@ func (w *worker) mirrorPGPKeys(pm *csaf.ProviderMetadata) error {
*pgpKey.URL, res.Status, res.StatusCode)
}

fingerprint := strings.ToUpper(string(pgpKey.Fingerprint))
fingerprint := strings.ToUpper(string(*pgpKey.Fingerprint))

localFile := filepath.Join(openPGPFolder, fingerprint+".asc")

Expand Down Expand Up @@ -323,7 +320,6 @@ func (w *worker) createAggregatorProvider() (*csaf.AggregatorCSAFProvider, error

// doMirrorTransaction performs an atomic directory swap.
func (w *worker) doMirrorTransaction() error {

webTarget := filepath.Join(
w.processor.cfg.Web, ".well-known", "csaf-aggregator", w.provider.Name)

Expand Down Expand Up @@ -432,7 +428,6 @@ func (w *worker) sign(data []byte) (string, error) {
}

func (w *worker) extractCategories(label string, advisory any) error {

// use provider or global categories
var categories []string
if w.provider.Categories != nil {
Expand Down Expand Up @@ -588,12 +583,12 @@ func (w *worker) mirrorFiles(tlpLabel csaf.TLPLabel, files []csaf.AdvisoryFile)
if err := os.MkdirAll(yearDir, 0755); err != nil {
return err
}
//log.Printf("created %s\n", yearDir)
// log.Printf("created %s\n", yearDir)
yearDirs[year] = yearDir
}

fname := filepath.Join(yearDir, filename)
//log.Printf("write: %s\n", fname)
// log.Printf("write: %s\n", fname)
data := content.Bytes()
if err := writeFileHashes(
fname, filename,
Expand All @@ -618,7 +613,6 @@ func (w *worker) mirrorFiles(tlpLabel csaf.TLPLabel, files []csaf.AdvisoryFile)
// If this fails it creates a signature itself with the configured key.
func (w *worker) downloadSignatureOrSign(url, fname string, data []byte) error {
sig, err := w.downloadSignature(url)

if err != nil {
if err != errNotFound {
w.log.Error("Could not find signature URL", "url", url, "err", err)
Expand Down
38 changes: 10 additions & 28 deletions cmd/csaf_checker/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,8 @@ type reporter interface {
report(*processor, *Domain)
}

var (
// errContinue indicates that the current check should continue.
errContinue = errors.New("continue")
)
// errContinue indicates that the current check should continue.
var errContinue = errors.New("continue")

type whereType byte

Expand Down Expand Up @@ -166,7 +164,6 @@ func (m *topicMessages) hasErrors() bool {

// newProcessor returns an initilaized processor.
func newProcessor(cfg *config) (*processor, error) {

var validator csaf.RemoteValidator

if cfg.RemoteValidator != "" {
Expand Down Expand Up @@ -239,7 +236,6 @@ func (p *processor) reset() {
// Then it calls the report method on each report from the given "reporters" parameter for each domain.
// It returns a pointer to the report and nil, otherwise an error.
func (p *processor) run(domains []string) (*Report, error) {

report := Report{
Date: ReportTime{Time: time.Now().UTC()},
Version: util.SemVersion,
Expand Down Expand Up @@ -296,7 +292,6 @@ func (p *processor) run(domains []string) (*Report, error) {

// fillMeta fills the report with extra informations from provider metadata.
func (p *processor) fillMeta(domain *Domain) error {

if p.pmd == nil {
return nil
}
Expand All @@ -322,7 +317,6 @@ func (p *processor) fillMeta(domain *Domain) error {
// domainChecks compiles a list of checks which should be performed
// for a given domain.
func (p *processor) domainChecks(domain string) []func(*processor, string) error {

// If we have a direct domain url we dont need to
// perform certain checks.
direct := strings.HasPrefix(domain, "https://")
Expand Down Expand Up @@ -392,7 +386,6 @@ func (p *processor) markChecked(s string, mask whereType) bool {
}

func (p *processor) checkRedirect(r *http.Request, via []*http.Request) error {

url := r.URL.String()
p.checkTLS(url)
if p.redirects == nil {
Expand Down Expand Up @@ -494,7 +487,6 @@ func (p *processor) usedAuthorizedClient() bool {

// rolieFeedEntries loads the references to the advisory files for a given feed.
func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) {

client := p.httpClient()
res, err := client.Get(feed)
p.badDirListings.use()
Expand Down Expand Up @@ -545,7 +537,6 @@ func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) {
var files []csaf.AdvisoryFile

rfeed.Entries(func(entry *csaf.Entry) {

// Filter if we have date checking.
if accept := p.cfg.Range; accept != nil {
if t := time.Time(entry.Updated); !t.IsZero() && !accept.Contains(t) {
Expand Down Expand Up @@ -911,7 +902,6 @@ func (p *processor) checkIndex(base string, mask whereType) error {
// of the fields' values and if they are sorted properly. Then it passes the files to the
// "integrity" functions. It returns error if some test fails, otherwise nil.
func (p *processor) checkChanges(base string, mask whereType) error {

bu, err := url.Parse(base)
if err != nil {
return err
Expand Down Expand Up @@ -970,8 +960,7 @@ func (p *processor) checkChanges(base string, mask whereType) error {
continue
}
path := r[pathColumn]
times, files =
append(times, t),
times, files = append(times, t),
append(files, csaf.PlainAdvisoryFile(path))
}
return times, files, nil
Expand Down Expand Up @@ -1144,7 +1133,6 @@ func (p *processor) checkMissing(string) error {
// checkInvalid goes over all found adivisories URLs and checks
// if file name conforms to standard.
func (p *processor) checkInvalid(string) error {

p.badDirListings.use()
var invalids []string

Expand All @@ -1166,7 +1154,6 @@ func (p *processor) checkInvalid(string) error {
// checkListing goes over all found adivisories URLs and checks
// if their parent directory is listable.
func (p *processor) checkListing(string) error {

p.badDirListings.use()

pgs := pages{}
Expand Down Expand Up @@ -1201,7 +1188,6 @@ func (p *processor) checkListing(string) error {
// checkWhitePermissions checks if the TLP:WHITE advisories are
// available with unprotected access.
func (p *processor) checkWhitePermissions(string) error {

var ids []string
for id, open := range p.labelChecker.whiteAdvisories {
if !open {
Expand All @@ -1227,7 +1213,6 @@ func (p *processor) checkWhitePermissions(string) error {
// According to the result, the respective error messages added to
// badProviderMetadata.
func (p *processor) checkProviderMetadata(domain string) bool {

p.badProviderMetadata.use()

client := p.httpClient()
Expand Down Expand Up @@ -1274,7 +1259,6 @@ func (p *processor) checkSecurity(domain string, legacy bool) (int, string) {

// checkSecurityFolder checks the security.txt in a given folder.
func (p *processor) checkSecurityFolder(folder string) string {

client := p.httpClient()
path := folder + "security.txt"
res, err := client.Get(path)
Expand Down Expand Up @@ -1341,7 +1325,6 @@ func (p *processor) checkSecurityFolder(folder string) string {
// and serves the "provider-metadata.json".
// It returns an empty string if all checks are passed, otherwise the errormessage.
func (p *processor) checkDNS(domain string) string {

client := p.httpClient()
path := "https://csaf.data.security." + domain
res, err := client.Get(path)
Expand All @@ -1351,7 +1334,6 @@ func (p *processor) checkDNS(domain string) string {
if res.StatusCode != http.StatusOK {
return fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status)

}
hash := sha256.New()
defer res.Body.Close()
Expand All @@ -1370,7 +1352,6 @@ func (p *processor) checkDNS(domain string) string {
// available under the /.well-known/csaf/ directory. Returns the errormessage if
// an error was encountered, or an empty string otherwise
func (p *processor) checkWellknown(domain string) string {

client := p.httpClient()
path := "https://" + domain + "/.well-known/csaf/provider-metadata.json"

Expand Down Expand Up @@ -1400,7 +1381,6 @@ func (p *processor) checkWellknown(domain string) string {
// The function returns nil, unless errors outside the checks were found.
// In that case, errors are returned.
func (p *processor) checkWellknownSecurityDNS(domain string) error {

warningsW := p.checkWellknown(domain)
// Security check for well known (default) and legacy location
warningsS, sDMessage := p.checkSecurity(domain, false)
Expand Down Expand Up @@ -1453,7 +1433,6 @@ func (p *processor) checkWellknownSecurityDNS(domain string) error {
// As a result of these a respective error messages are passed to badPGP method
// in case of errors. It returns nil if all checks are passed.
func (p *processor) checkPGPKeys(_ string) error {

p.badPGPs.use()

src, err := p.expr.Eval("$.public_openpgp_keys", p.pmd)
Expand Down Expand Up @@ -1512,19 +1491,22 @@ func (p *processor) checkPGPKeys(_ string) error {
defer res.Body.Close()
return crypto.NewKeyFromArmoredReader(res.Body)
}()

if err != nil {
p.badPGPs.error("Reading public OpenPGP key %s failed: %v", u, err)
continue
}

if key.Fingerprint == "" {
if key.Fingerprint == nil {
p.badPGPs.warn("No fingerprint for public OpenPGP key found.")
continue
}

if !strings.EqualFold(ckey.GetFingerprint(), string(key.Fingerprint)) {
p.badPGPs.error("Given Fingerprint (%q) of public OpenPGP key %q does not match remotely loaded (%q).", string(key.Fingerprint), u, ckey.GetFingerprint())
if *key.Fingerprint == "" {
p.badPGPs.warn("Empty fingerprint for public OpenPGP key found.")
}

if !strings.EqualFold(ckey.GetFingerprint(), string(*key.Fingerprint)) {
p.badPGPs.error("Given Fingerprint (%q) of public OpenPGP key %q does not match remotely loaded (%q).", string(*key.Fingerprint), u, ckey.GetFingerprint())
continue
}
if p.keys == nil {
Expand Down
14 changes: 7 additions & 7 deletions cmd/csaf_downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ type downloader struct {
const failedValidationDir = "failed_validation"

func newDownloader(cfg *config) (*downloader, error) {

var validator csaf.RemoteValidator

if cfg.RemoteValidator != "" {
Expand Down Expand Up @@ -103,7 +102,6 @@ func logRedirect(req *http.Request, via []*http.Request) error {
}

func (d *downloader) httpClient() util.Client {

hClient := http.Client{}

if d.cfg.verbose() {
Expand Down Expand Up @@ -253,7 +251,6 @@ func (d *downloader) downloadFiles(
label csaf.TLPLabel,
files []csaf.AdvisoryFile,
) error {

var (
advisoryCh = make(chan csaf.AdvisoryFile)
errorCh = make(chan error)
Expand Down Expand Up @@ -303,7 +300,6 @@ func (d *downloader) loadOpenPGPKeys(
base *url.URL,
expr *util.PathEval,
) error {

src, err := expr.Eval("$.public_openpgp_keys", doc)
if err != nil {
// no keys.
Expand Down Expand Up @@ -357,7 +353,6 @@ func (d *downloader) loadOpenPGPKeys(
defer res.Body.Close()
return crypto.NewKeyFromArmoredReader(res.Body)
}()

if err != nil {
slog.Warn(
"Reading public OpenPGP key failed",
Expand All @@ -366,12 +361,17 @@ func (d *downloader) loadOpenPGPKeys(
continue
}

if key.Fingerprint == "" {
if key.Fingerprint == nil {
slog.Warn("No fingerprint for public OpenPGP key found.")
continue
}

if !strings.EqualFold(ckey.GetFingerprint(), string(key.Fingerprint)) {
if *key.Fingerprint == "" {
slog.Warn("Empty fingerprint for public OpenPGP key found.")
continue
}

if !strings.EqualFold(ckey.GetFingerprint(), string(*key.Fingerprint)) {
slog.Warn(
"Fingerprint of public OpenPGP key does not match remotely loaded",
"url", u, "fingerprint", key.Fingerprint, "remote-fingerprint", ckey.GetFingerprint())
Expand Down
12 changes: 5 additions & 7 deletions csaf/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ var fingerprintPattern = patternUnmarshal(`^[0-9a-fA-F]{40,}$`)
// PGPKey is location and the fingerprint of the key
// used to sign the CSAF documents.
type PGPKey struct {
Fingerprint Fingerprint `json:"fingerprint,omitempty"`
URL *string `json:"url"` // required
Fingerprint *Fingerprint `json:"fingerprint,omitempty"`
URL *string `json:"url"` // required
}

// Category is the category of the CSAF feed.
Expand Down Expand Up @@ -575,7 +575,6 @@ func (d *Distribution) Validate() error {
// Validate checks if the provider metadata is valid.
// Returns an error if the validation fails otherwise nil.
func (pmd *ProviderMetadata) Validate() error {

switch {
case pmd.CanonicalURL == nil:
return errors.New("canonical_url is mandatory")
Expand Down Expand Up @@ -616,13 +615,14 @@ func (pmd *ProviderMetadata) SetLastUpdated(t time.Time) {
// If there is no such key it is append to the list of keys.
func (pmd *ProviderMetadata) SetPGP(fingerprint, url string) {
for i := range pmd.PGPKeys {
if strings.EqualFold(string(pmd.PGPKeys[i].Fingerprint), fingerprint) {
if strings.EqualFold(string(*pmd.PGPKeys[i].Fingerprint), fingerprint) {
pmd.PGPKeys[i].URL = &url
return
}
}
f := Fingerprint(fingerprint)
pmd.PGPKeys = append(pmd.PGPKeys, PGPKey{
Fingerprint: Fingerprint(fingerprint),
Fingerprint: &f,
URL: &url,
})
}
Expand All @@ -648,7 +648,6 @@ func NewProviderMetadataDomain(domain string, tlps []TLPLabel) *ProviderMetadata
// NewProviderMetadataPrefix creates a new provider with a given prefix
// and tlps feeds.
func NewProviderMetadataPrefix(prefix string, tlps []TLPLabel) *ProviderMetadata {

pm := NewProviderMetadata(
prefix + "/provider-metadata.json")

Expand Down Expand Up @@ -693,7 +692,6 @@ func (pmd *ProviderMetadata) WriteTo(w io.Writer) (int64, error) {

// LoadProviderMetadata loads a metadata provider from a reader.
func LoadProviderMetadata(r io.Reader) (*ProviderMetadata, error) {

var pmd ProviderMetadata
dec := json.NewDecoder(r)
if err := dec.Decode(&pmd); err != nil {
Expand Down

0 comments on commit 7b1c350

Please sign in to comment.