aboutsummaryrefslogtreecommitdiff
path: root/cpematch
diff options
context:
space:
mode:
Diffstat (limited to 'cpematch')
-rw-r--r--cpematch/cpematch.go31
-rw-r--r--cpematch/cpematch_test.go100
-rw-r--r--cpematch/testdata/test-0.json.gzbin0 -> 291 bytes
3 files changed, 131 insertions, 0 deletions
diff --git a/cpematch/cpematch.go b/cpematch/cpematch.go
new file mode 100644
index 0000000..0bae622
--- /dev/null
+++ b/cpematch/cpematch.go
@@ -0,0 +1,31 @@
+// CPE match feed 1.0 parser.
+//
+// Latest CPE match feed available from here:
+// https://nvd.nist.gov/vuln/data-feeds#cpeMatch
+//
+// JSON schema available here:
+// https://csrc.nist.gov/schema/cpematch/feed/1.0/nvd_cpematch_feed_json_1.0.schema
+package cpematch
+
+// CPE name
+type Name struct {
+ Cpe22Uri string `json:"cpe22Uri"`
+ Cpe23Uri string `json:"cpe23Uri"`
+}
+
+// CPE match string or range
+type Match struct {
+ Vulnerable *bool `json:"vulnerable"`
+ Cpe22Uri string `json:"cpe22Uri"`
+ Cpe23Uri string `json:"cpe23Uri"`
+ VersionStartExcluding string `json:"versionStartExcluding"`
+ VersionStartIncluding string `json:"versionStartIncluding"`
+ VersionEndExcluding string `json:"versionEndExcluding"`
+ VersionEndIncluding string `json:"versionEndIncluding"`
+ Names []Name `json:"cpe_name"` // CPE match strings
+}
+
+// CPE matches
+type Matches struct {
+ Matches []Match `json:"matches"` // Array of CPE matches
+}
diff --git a/cpematch/cpematch_test.go b/cpematch/cpematch_test.go
new file mode 100644
index 0000000..7d69410
--- /dev/null
+++ b/cpematch/cpematch_test.go
@@ -0,0 +1,100 @@
+package cpematch
+
+import (
+ "compress/gzip"
+ "encoding/json"
+ "os"
+ "reflect"
+ "testing"
+)
+
+func TestMatchesUnmarshal(t *testing.T) {
+ // expected data
+ exp := Matches {
+ Matches: []Match {
+ Match {
+ Cpe23Uri: "cpe:2.3:a:101_project:101:*:*:*:*:*:node.js:*:*",
+ VersionStartIncluding: "1.0.0",
+ VersionEndIncluding: "1.6.3",
+ Names: []Name {
+ Name {
+ Cpe23Uri: "cpe:2.3:a:101_project:101:1.0.0:*:*:*:*:node.js:*:*",
+ },
+
+ Name {
+ Cpe23Uri: "cpe:2.3:a:101_project:101:1.1.0:*:*:*:*:node.js:*:*",
+ },
+
+ Name {
+ Cpe23Uri: "cpe:2.3:a:101_project:101:1.1.1:*:*:*:*:node.js:*:*",
+ },
+ },
+ },
+
+ Match {
+ Cpe23Uri: "cpe:2.3:a:1password:1password:*:*:*:*:*:macos:*:*",
+ VersionStartIncluding: "7.7.0",
+ VersionEndExcluding: "7.8.7",
+ Names: []Name {
+ Name {
+ Cpe23Uri: "cpe:2.3:a:1password:1password:7.7.0:*:*:*:*:macos:*:*",
+ },
+ },
+ },
+
+ Match {
+ Cpe23Uri: "cpe:2.3:a:zimbra:collaboration:*:*:*:*:*:*:*:*",
+ VersionStartExcluding: "8.8.0",
+ VersionEndExcluding: "8.8.15",
+ Names: []Name {
+ Name {
+ Cpe23Uri: "cpe:2.3:a:zimbra:collaboration:8.8.6:*:*:*:*:*:*:*",
+ },
+
+ Name {
+ Cpe23Uri: "cpe:2.3:a:zimbra:collaboration:8.8.7:*:*:*:*:*:*:*",
+ },
+
+ Name {
+ Cpe23Uri: "cpe:2.3:a:zimbra:collaboration:8.8.8:-:*:*:*:*:*:*",
+ },
+
+ Name {
+ Cpe23Uri: "cpe:2.3:a:zimbra:collaboration:8.8.8:p1:*:*:*:*:*:*",
+ },
+ },
+ },
+ },
+ }
+
+ // open test data
+ f, err := os.Open("testdata/test-0.json.gz")
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer f.Close()
+
+ // create gzip reader
+ gz, err := gzip.NewReader(f)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer gz.Close()
+
+ // create json decoder
+ d := json.NewDecoder(gz)
+ var got Matches
+
+ // decode match data, check for error
+ if err := d.Decode(&got); err != nil {
+ t.Error(err)
+ return
+ }
+
+ // check for match
+ if !reflect.DeepEqual(got, exp) {
+ t.Errorf("got \"%v\", exp \"%v\"", got, exp)
+ }
+}
diff --git a/cpematch/testdata/test-0.json.gz b/cpematch/testdata/test-0.json.gz
new file mode 100644
index 0000000..611bd58
--- /dev/null
+++ b/cpematch/testdata/test-0.json.gz
Binary files differ