diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml
index 9fe9591..0971941 100644
--- a/.github/workflows/update.yml
+++ b/.github/workflows/update.yml
@@ -95,6 +95,10 @@ jobs:
name: Rocky Linux Security Advisory
run: ./vuln-list-update -target rocky
+ - if: always()
+ name: CBL-Mariner Vulnerability Data
+ run: ./vuln-list-update -target mariner
+
- if: always()
name: OSV Database
run: ./vuln-list-update -target osv
diff --git a/README.md b/README.md
index 674888f..908ddfa 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ https://github.com/aquasecurity/vuln-list/
$ vuln-list-update -h
Usage of vuln-list-update:
-target string
- update target (nvd, alpine, redhat, debian, ubuntu)
+ update target (nvd, alpine, alpine-unfixed, redhat, redhat-oval, debian, debian-oval, ubuntu, amazon, oracle-oval, suse-cvrf, photon, arch-linux, ghsa, glad, cwe, osv, go-vulndb, mariner)
-years string
update years (only redhat)
```
diff --git a/main.go b/main.go
index e61d7fb..674c182 100644
--- a/main.go
+++ b/main.go
@@ -25,6 +25,7 @@ import (
"github.com/aquasecurity/vuln-list-update/git"
"github.com/aquasecurity/vuln-list-update/glad"
govulndb "github.com/aquasecurity/vuln-list-update/go-vulndb"
+ "github.com/aquasecurity/vuln-list-update/mariner"
"github.com/aquasecurity/vuln-list-update/nvd"
oracleoval "github.com/aquasecurity/vuln-list-update/oracle/oval"
"github.com/aquasecurity/vuln-list-update/osv"
@@ -45,7 +46,7 @@ const (
var (
target = flag.String("target", "", "update target (nvd, alpine, alpine-unfixed, redhat, redhat-oval, "+
- "debian, debian-oval, ubuntu, amazon, oracle-oval, suse-cvrf, photon, arch-linux, ghsa, glad, cwe, osv, go-vulndb)")
+ "debian, debian-oval, ubuntu, amazon, oracle-oval, suse-cvrf, photon, arch-linux, ghsa, glad, cwe, osv, go-vulndb, mariner)")
years = flag.String("years", "", "update years (only redhat)")
)
@@ -214,6 +215,12 @@ func run() error {
return xerrors.Errorf("Go Vulnerability Database update error: %w", err)
}
commitMsg = "Go Vulnerability Database"
+ case "mariner":
+ src := mariner.NewConfig()
+ if err := src.Update(); err != nil {
+ return xerrors.Errorf("CBL-Mariner Vulnerability Data update error: %w", err)
+ }
+ commitMsg = "CBL-Mariner Vulnerability Data"
default:
return xerrors.New("unknown target")
}
diff --git a/mariner/mariner.go b/mariner/mariner.go
new file mode 100644
index 0000000..cddd3db
--- /dev/null
+++ b/mariner/mariner.go
@@ -0,0 +1,175 @@
+package mariner
+
+import (
+ "context"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/cheggaaa/pb"
+ "golang.org/x/xerrors"
+
+ "github.com/aquasecurity/vuln-list-update/utils"
+)
+
+const (
+ repoURL = "https://github.com/microsoft/CBL-MarinerVulnerabilityData/archive/refs/heads/main.tar.gz//CBL-MarinerVulnerabilityData-main"
+ cblDir = "mariner" // CBL-Mariner Vulnerability Data
+ retry = 3
+
+ testsDir = "tests"
+ objectsDir = "objects"
+ statesDir = "states"
+ definitionsDir = "definitions"
+)
+
+var (
+ ErrInvalidCVEFormat = errors.New("invalid CVE-ID format")
+ ErrNonCVEID = errors.New("discovered non-CVE-ID")
+)
+
+type Config struct {
+ *options
+}
+
+type option func(*options)
+
+type options struct {
+ url string
+ dir string
+ retry int
+}
+
+func WithURL(url string) option {
+ return func(opts *options) { opts.url = url }
+}
+
+func WithDir(dir string) option {
+ return func(opts *options) { opts.dir = dir }
+}
+
+func WithRetry(retry int) option {
+ return func(opts *options) { opts.retry = retry }
+}
+
+func NewConfig(opts ...option) Config {
+ o := &options{
+ url: repoURL,
+ dir: filepath.Join(utils.VulnListDir(), cblDir),
+ retry: retry,
+ }
+
+ for _, opt := range opts {
+ opt(o)
+ }
+
+ return Config{
+ options: o,
+ }
+}
+
+func (c Config) Update() error {
+ ctx := context.Background()
+
+ log.Printf("Remove CBL-Mariner Vulnerability Data directory %sn", c.dir)
+ if err := os.RemoveAll(c.dir); err != nil {
+ return xerrors.Errorf("failed to remove CBL-Mariner Vulnerability Data directory: %w", err)
+ }
+
+ log.Print("Fetching CBL-Mariner Vulnerability Data")
+ tmpDir, err := utils.DownloadToTempDir(ctx, c.url)
+ if err != nil {
+ return xerrors.Errorf("failed to retrieve CBL-Mariner Vulnerability Data: %w", err)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ entries, err := os.ReadDir(tmpDir)
+ if err != nil {
+ return xerrors.Errorf("failed to read directory: %w", err)
+ }
+
+ for _, entry := range entries {
+ if entry.IsDir() {
+ continue
+ }
+
+ if !strings.HasPrefix(entry.Name(), "cbl-mariner-") {
+ continue
+ }
+ if filepath.Ext(entry.Name()) != ".xml" {
+ continue
+ }
+
+ osVersoin := strings.TrimSuffix(strings.TrimSuffix(strings.TrimPrefix(entry.Name(), "cbl-mariner-"), "-oval.xml"), "-preview")
+ if err := c.update(osVersoin, filepath.Join(tmpDir, entry.Name())); err != nil {
+ return xerrors.Errorf("failed to update oval data: %w", err)
+ }
+ }
+ return nil
+}
+
+func (c Config) update(version, path string) error {
+ f, err := os.Open(path)
+ if err != nil {
+ return xerrors.Errorf("failed to open file: %w", err)
+ }
+
+ var oval OvalDefinitions
+ if err := xml.NewDecoder(f).Decode(&oval); err != nil {
+ return xerrors.Errorf("failed to decode xml: %w", err)
+ }
+ dirPath := filepath.Join(c.dir, version)
+
+ // write tests/tests.json file
+ if err := utils.Write(filepath.Join(dirPath, testsDir, "tests.json"), oval.Tests); err != nil {
+ return xerrors.Errorf("failed to write tests: %w", err)
+ }
+
+ // write objects/objects.json file
+ if err := utils.Write(filepath.Join(dirPath, objectsDir, "objects.json"), oval.Objects); err != nil {
+ return xerrors.Errorf("failed to write objects: %w", err)
+ }
+
+ // write states/states.json file
+ if err := utils.Write(filepath.Join(dirPath, statesDir, "states.json"), oval.States); err != nil {
+ return xerrors.Errorf("failed to write states: %w", err)
+ }
+
+ // write definitions
+ bar := pb.StartNew(len(oval.Definitions.Definition))
+ for _, def := range oval.Definitions.Definition {
+ vulnID := def.Metadata.Reference.RefID
+
+ if err := c.saveAdvisoryPerYear(filepath.Join(dirPath, definitionsDir), vulnID, def); err != nil {
+ return xerrors.Errorf("failed to save advisory per year: %w", err)
+ }
+
+ bar.Increment()
+ }
+ bar.Finish()
+
+ return nil
+}
+
+func (c Config) saveAdvisoryPerYear(dirName string, vulnID string, def Definition) error {
+ if !strings.HasPrefix(vulnID, "CVE") {
+ log.Printf("discovered non-CVE-ID: %s", vulnID)
+ return ErrNonCVEID
+ }
+
+ s := strings.Split(vulnID, "-")
+ if len(s) != 3 {
+ log.Printf("invalid CVE-ID format: %s", vulnID)
+ return ErrInvalidCVEFormat
+ }
+
+ yearDir := filepath.Join(dirName, s[1])
+ if err := utils.Write(filepath.Join(yearDir, fmt.Sprintf("%s.json", vulnID)), def); err != nil {
+ return xerrors.Errorf("unable to write a JSON file: %w", err)
+ }
+ return nil
+}
diff --git a/mariner/mariner_test.go b/mariner/mariner_test.go
new file mode 100644
index 0000000..7772253
--- /dev/null
+++ b/mariner/mariner_test.go
@@ -0,0 +1,68 @@
+package mariner_test
+
+import (
+ "io/fs"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/aquasecurity/vuln-list-update/mariner"
+)
+
+func TestUpdate(t *testing.T) {
+ tests := []struct {
+ name string
+ inputFile string
+ wantErr string
+ }{
+ {
+ name: "happy path",
+ inputFile: "file::testdata/happy",
+ },
+ {
+ name: "sad path, invalid xml",
+ inputFile: "file::testdata/sad",
+ wantErr: "failed to decode xml",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ tmpDir := t.TempDir()
+ cc := mariner.NewConfig(mariner.WithURL(tt.inputFile), mariner.WithDir(tmpDir), mariner.WithRetry(0))
+
+ err := cc.Update()
+ if tt.wantErr != "" {
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), tt.wantErr)
+ return
+ }
+ require.NoError(t, err)
+
+ err = filepath.WalkDir(tmpDir, func(path string, d fs.DirEntry, err error) error {
+ require.NoError(t, err, tt.name)
+ if !d.Type().IsRegular() {
+ return nil
+ }
+
+ got, err := os.ReadFile(path)
+ require.NoError(t, err, path)
+
+ rel, err := filepath.Rel(tmpDir, path)
+ require.NoError(t, err, path)
+
+ goldenPath := filepath.Join("testdata", "golden", "mariner", rel)
+ want, err := os.ReadFile(goldenPath)
+ require.NoError(t, err, goldenPath)
+
+ assert.JSONEq(t, string(want), string(got), path)
+
+ return nil
+ })
+ require.NoError(t, err, tt.name)
+ })
+ }
+}
diff --git a/mariner/testdata/golden/mariner/1.0/definitions/2008/CVE-2008-3914.json b/mariner/testdata/golden/mariner/1.0/definitions/2008/CVE-2008-3914.json
new file mode 100644
index 0000000..507ccf8
--- /dev/null
+++ b/mariner/testdata/golden/mariner/1.0/definitions/2008/CVE-2008-3914.json
@@ -0,0 +1,29 @@
+{
+ "Class": "vulnerability",
+ "ID": "oval:com.microsoft.cbl-mariner:def:3173",
+ "Version": "1643374849",
+ "Metadata": {
+ "Title": "CVE-2008-3914 affecting package clamav 0.101.2",
+ "Affected": {
+ "Family": "unix",
+ "Platform": "CBL-Mariner"
+ },
+ "Reference": {
+ "RefID": "CVE-2008-3914",
+ "RefURL": "https://nvd.nist.gov/vuln/detail/CVE-2008-3914",
+ "Source": "CVE"
+ },
+ "Patchable": "true",
+ "AdvisoryDate": "2021-05-06T23:56:51Z",
+ "AdvisoryID": "3173",
+ "Severity": "Critical",
+ "Description": "CVE-2008-3914 affecting package clamav 0.101.2. An upgraded version of the package is available that resolves this issue."
+ },
+ "Criteria": {
+ "Operator": "AND",
+ "Criterion": {
+ "Comment": "Package clamav is earlier than 0.103.2-1, affected by CVE-2008-3914",
+ "TestRef": "oval:com.microsoft.cbl-mariner:tst:1643374849000003"
+ }
+ }
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/1.0/definitions/2018/CVE-2018-25012.json b/mariner/testdata/golden/mariner/1.0/definitions/2018/CVE-2018-25012.json
new file mode 100644
index 0000000..1d69889
--- /dev/null
+++ b/mariner/testdata/golden/mariner/1.0/definitions/2018/CVE-2018-25012.json
@@ -0,0 +1,29 @@
+{
+ "Class": "vulnerability",
+ "ID": "oval:com.microsoft.cbl-mariner:def:4209",
+ "Version": "1643374849",
+ "Metadata": {
+ "Title": "CVE-2018-25012 affecting package libwebp 1.0.0",
+ "Affected": {
+ "Family": "unix",
+ "Platform": "CBL-Mariner"
+ },
+ "Reference": {
+ "RefID": "CVE-2018-25012",
+ "RefURL": "https://nvd.nist.gov/vuln/detail/CVE-2018-25012",
+ "Source": "CVE"
+ },
+ "Patchable": "true",
+ "AdvisoryDate": "2021-06-09T03:50:29Z",
+ "AdvisoryID": "4209",
+ "Severity": "Critical",
+ "Description": "CVE-2018-25012 affecting package libwebp 1.0.0. An upgraded version of the package is available that resolves this issue."
+ },
+ "Criteria": {
+ "Operator": "AND",
+ "Criterion": {
+ "Comment": "Package libwebp is earlier than 1.0.3-1, affected by CVE-2018-25012",
+ "TestRef": "oval:com.microsoft.cbl-mariner:tst:1643374849000151"
+ }
+ }
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/1.0/definitions/2021/CVE-2021-35942.json b/mariner/testdata/golden/mariner/1.0/definitions/2021/CVE-2021-35942.json
new file mode 100644
index 0000000..63e61e8
--- /dev/null
+++ b/mariner/testdata/golden/mariner/1.0/definitions/2021/CVE-2021-35942.json
@@ -0,0 +1,29 @@
+{
+ "Class": "vulnerability",
+ "ID": "oval:com.microsoft.cbl-mariner:def:4820",
+ "Version": "1643374849",
+ "Metadata": {
+ "Title": "CVE-2021-35942 affecting package glibc 2.28",
+ "Affected": {
+ "Family": "unix",
+ "Platform": "CBL-Mariner"
+ },
+ "Reference": {
+ "RefID": "CVE-2021-35942",
+ "RefURL": "https://nvd.nist.gov/vuln/detail/CVE-2021-35942",
+ "Source": "CVE"
+ },
+ "Patchable": "true",
+ "AdvisoryDate": "2021-08-11T06:39:32Z",
+ "AdvisoryID": "4820",
+ "Severity": "Critical",
+ "Description": "CVE-2021-35942 affecting package glibc 2.28. A patched version of the package is available."
+ },
+ "Criteria": {
+ "Operator": "AND",
+ "Criterion": {
+ "Comment": "Package glibc is earlier than 2.28-19, affected by CVE-2021-35942",
+ "TestRef": "oval:com.microsoft.cbl-mariner:tst:1643374849000145"
+ }
+ }
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/1.0/objects/objects.json b/mariner/testdata/golden/mariner/1.0/objects/objects.json
new file mode 100644
index 0000000..69b5a25
--- /dev/null
+++ b/mariner/testdata/golden/mariner/1.0/objects/objects.json
@@ -0,0 +1,19 @@
+{
+ "RpminfoObjects": [
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:obj:1643374849000004",
+ "Version": "1643374849",
+ "Name": "clamav"
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:obj:1643374849000051",
+ "Version": "1643374849",
+ "Name": "glibc"
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:obj:1643374849000067",
+ "Version": "1643374849",
+ "Name": "libwebp"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/1.0/states/states.json b/mariner/testdata/golden/mariner/1.0/states/states.json
new file mode 100644
index 0000000..c43080d
--- /dev/null
+++ b/mariner/testdata/golden/mariner/1.0/states/states.json
@@ -0,0 +1,31 @@
+{
+ "RpminfoState": [
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:ste:1643374849000005",
+ "Version": "1643374849",
+ "Evr": {
+ "Text": "0:0.103.2-1.cm1",
+ "Datatype": "evr_string",
+ "Operation": "less than"
+ }
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:ste:1643374849000068",
+ "Version": "1643374849",
+ "Evr": {
+ "Text": "0:1.0.3-1.cm1",
+ "Datatype": "evr_string",
+ "Operation": "less than"
+ }
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:ste:1643374849000146",
+ "Version": "1643374849",
+ "Evr": {
+ "Text": "0:2.28-19.cm1",
+ "Datatype": "evr_string",
+ "Operation": "less than"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/1.0/tests/tests.json b/mariner/testdata/golden/mariner/1.0/tests/tests.json
new file mode 100644
index 0000000..44a3dd3
--- /dev/null
+++ b/mariner/testdata/golden/mariner/1.0/tests/tests.json
@@ -0,0 +1,40 @@
+{
+ "RpminfoTests": [
+ {
+ "Check": "at least one",
+ "Comment": "Package clamav is earlier than 0.103.2-1, affected by CVE-2008-3914",
+ "ID": "oval:com.microsoft.cbl-mariner:tst:1643374849000003",
+ "Version": "1643374849",
+ "Object": {
+ "ObjectRef": "oval:com.microsoft.cbl-mariner:obj:1643374849000004"
+ },
+ "State": {
+ "StateRef": "oval:com.microsoft.cbl-mariner:ste:1643374849000005"
+ }
+ },
+ {
+ "Check": "at least one",
+ "Comment": "Package glibc is earlier than 2.28-19, affected by CVE-2021-35942",
+ "ID": "oval:com.microsoft.cbl-mariner:tst:1643374849000145",
+ "Version": "1643374849",
+ "Object": {
+ "ObjectRef": "oval:com.microsoft.cbl-mariner:obj:1643374849000051"
+ },
+ "State": {
+ "StateRef": "oval:com.microsoft.cbl-mariner:ste:1643374849000146"
+ }
+ },
+ {
+ "Check": "at least one",
+ "Comment": "Package libwebp is earlier than 1.0.3-1, affected by CVE-2018-25012",
+ "ID": "oval:com.microsoft.cbl-mariner:tst:1643374849000151",
+ "Version": "1643374849",
+ "Object": {
+ "ObjectRef": "oval:com.microsoft.cbl-mariner:obj:1643374849000067"
+ },
+ "State": {
+ "StateRef": "oval:com.microsoft.cbl-mariner:ste:1643374849000068"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/2.0/definitions/2014/CVE-2014-8139.json b/mariner/testdata/golden/mariner/2.0/definitions/2014/CVE-2014-8139.json
new file mode 100644
index 0000000..fa9a067
--- /dev/null
+++ b/mariner/testdata/golden/mariner/2.0/definitions/2014/CVE-2014-8139.json
@@ -0,0 +1,28 @@
+{
+ "Class": "vulnerability",
+ "ID": "oval:com.microsoft.cbl-mariner:def:6933",
+ "Version": "1643374850",
+ "Metadata": {
+ "Title": "CVE-2014-8139 affecting package unzip 6.0",
+ "Affected": {
+ "Family": "unix",
+ "Platform": "CBL-Mariner"
+ },
+ "Reference": {
+ "RefID": "CVE-2014-8139",
+ "RefURL": "https://nvd.nist.gov/vuln/detail/CVE-2014-8139",
+ "Source": "CVE"
+ },
+ "Patchable": "false",
+ "AdvisoryID": "6933",
+ "Severity": "High",
+ "Description": "CVE-2014-8139 affecting package unzip 6.0. No patch is available currently."
+ },
+ "Criteria": {
+ "Operator": "AND",
+ "Criterion": {
+ "Comment": "Package unzip is installed with version 6.0 or earlier",
+ "TestRef": "oval:com.microsoft.cbl-mariner:tst:1643374850000269"
+ }
+ }
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/2.0/definitions/2021/CVE-2021-39924.json b/mariner/testdata/golden/mariner/2.0/definitions/2021/CVE-2021-39924.json
new file mode 100644
index 0000000..638b96d
--- /dev/null
+++ b/mariner/testdata/golden/mariner/2.0/definitions/2021/CVE-2021-39924.json
@@ -0,0 +1,28 @@
+{
+ "Class": "vulnerability",
+ "ID": "oval:com.microsoft.cbl-mariner:def:7412",
+ "Version": "1643374850",
+ "Metadata": {
+ "Title": "CVE-2021-39924 affecting package wireshark 3.4.4",
+ "Affected": {
+ "Family": "unix",
+ "Platform": "CBL-Mariner"
+ },
+ "Reference": {
+ "RefID": "CVE-2021-39924",
+ "RefURL": "https://nvd.nist.gov/vuln/detail/CVE-2021-39924",
+ "Source": "CVE"
+ },
+ "Patchable": "false",
+ "AdvisoryID": "7412",
+ "Severity": "High",
+ "Description": "CVE-2021-39924 affecting package wireshark 3.4.4. No patch is available currently."
+ },
+ "Criteria": {
+ "Operator": "AND",
+ "Criterion": {
+ "Comment": "Package wireshark is installed with version 3.4.4 or earlier",
+ "TestRef": "oval:com.microsoft.cbl-mariner:tst:1643374850000435"
+ }
+ }
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/2.0/definitions/2022/CVE-2022-21309.json b/mariner/testdata/golden/mariner/2.0/definitions/2022/CVE-2022-21309.json
new file mode 100644
index 0000000..d9304ed
--- /dev/null
+++ b/mariner/testdata/golden/mariner/2.0/definitions/2022/CVE-2022-21309.json
@@ -0,0 +1,28 @@
+{
+ "Class": "vulnerability",
+ "ID": "oval:com.microsoft.cbl-mariner:def:7700",
+ "Version": "1643374850",
+ "Metadata": {
+ "Title": "CVE-2022-21309 affecting package mysql 8.0.24",
+ "Affected": {
+ "Family": "unix",
+ "Platform": "CBL-Mariner"
+ },
+ "Reference": {
+ "RefID": "CVE-2022-21309",
+ "RefURL": "https://nvd.nist.gov/vuln/detail/CVE-2022-21309",
+ "Source": "CVE"
+ },
+ "Patchable": "false",
+ "AdvisoryID": "7700",
+ "Severity": "Medium",
+ "Description": "CVE-2022-21309 affecting package mysql 8.0.24. No patch is available currently."
+ },
+ "Criteria": {
+ "Operator": "AND",
+ "Criterion": {
+ "Comment": "Package mysql is installed with version 8.0.24 or earlier",
+ "TestRef": "oval:com.microsoft.cbl-mariner:tst:1643374850000854"
+ }
+ }
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/2.0/objects/objects.json b/mariner/testdata/golden/mariner/2.0/objects/objects.json
new file mode 100644
index 0000000..e9ee408
--- /dev/null
+++ b/mariner/testdata/golden/mariner/2.0/objects/objects.json
@@ -0,0 +1,19 @@
+{
+ "RpminfoObjects": [
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:obj:1643374850000123",
+ "Version": "1643374850",
+ "Name": "unzip"
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:obj:1643374850000429",
+ "Version": "1643374850",
+ "Name": "wireshark"
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:obj:1643374850000669",
+ "Version": "1643374850",
+ "Name": "mysql"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/2.0/states/states.json b/mariner/testdata/golden/mariner/2.0/states/states.json
new file mode 100644
index 0000000..ebd7afa
--- /dev/null
+++ b/mariner/testdata/golden/mariner/2.0/states/states.json
@@ -0,0 +1,31 @@
+{
+ "RpminfoState": [
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:ste:1643374850000031",
+ "Version": "1643374850",
+ "Evr": {
+ "Text": "0:3.4.4-2.cm1",
+ "Datatype": "evr_string",
+ "Operation": "less than or equal"
+ }
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:ste:1643374850000124",
+ "Version": "1643374850",
+ "Evr": {
+ "Text": "0:6.0-19.cm1",
+ "Datatype": "evr_string",
+ "Operation": "less than or equal"
+ }
+ },
+ {
+ "ID": "oval:com.microsoft.cbl-mariner:ste:1643374850000670",
+ "Version": "1643374850",
+ "Evr": {
+ "Text": "0:8.0.24-1.cm1",
+ "Datatype": "evr_string",
+ "Operation": "less than or equal"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mariner/testdata/golden/mariner/2.0/tests/tests.json b/mariner/testdata/golden/mariner/2.0/tests/tests.json
new file mode 100644
index 0000000..2028ecb
--- /dev/null
+++ b/mariner/testdata/golden/mariner/2.0/tests/tests.json
@@ -0,0 +1,40 @@
+{
+ "RpminfoTests": [
+ {
+ "Check": "at least one",
+ "Comment": "Package unzip is installed with version 6.0 or earlier",
+ "ID": "oval:com.microsoft.cbl-mariner:tst:1643374850000269",
+ "Version": "1643374850",
+ "Object": {
+ "ObjectRef": "oval:com.microsoft.cbl-mariner:obj:1643374850000123"
+ },
+ "State": {
+ "StateRef": "oval:com.microsoft.cbl-mariner:ste:1643374850000124"
+ }
+ },
+ {
+ "Check": "at least one",
+ "Comment": "Package wireshark is installed with version 3.4.4 or earlier",
+ "ID": "oval:com.microsoft.cbl-mariner:tst:1643374850000435",
+ "Version": "1643374850",
+ "Object": {
+ "ObjectRef": "oval:com.microsoft.cbl-mariner:obj:1643374850000429"
+ },
+ "State": {
+ "StateRef": "oval:com.microsoft.cbl-mariner:ste:1643374850000031"
+ }
+ },
+ {
+ "Check": "at least one",
+ "Comment": "Package mysql is installed with version 8.0.24 or earlier",
+ "ID": "oval:com.microsoft.cbl-mariner:tst:1643374850000854",
+ "Version": "1643374850",
+ "Object": {
+ "ObjectRef": "oval:com.microsoft.cbl-mariner:obj:1643374850000669"
+ },
+ "State": {
+ "StateRef": "oval:com.microsoft.cbl-mariner:ste:1643374850000670"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mariner/testdata/happy/README.md b/mariner/testdata/happy/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/mariner/testdata/happy/SECURITY.md b/mariner/testdata/happy/SECURITY.md
new file mode 100644
index 0000000..e69de29
diff --git a/mariner/testdata/happy/cbl-mariner-1.0-oval.xml b/mariner/testdata/happy/cbl-mariner-1.0-oval.xml
new file mode 100644
index 0000000..64b097d
--- /dev/null
+++ b/mariner/testdata/happy/cbl-mariner-1.0-oval.xml
@@ -0,0 +1,98 @@
+
+
+ CBL-Mariner OVAL Definition Generator
+ 8
+ 5.11
+ 2022-01-28T13:00:49.330011518Z
+ 1643374849
+
+
+
+
+ CVE-2008-3914 affecting package clamav 0.101.2
+
+ CBL-Mariner
+
+
+ true
+ 2021-05-06T23:56:51Z
+ 3173
+ Critical
+ CVE-2008-3914 affecting package clamav 0.101.2. An upgraded version of the package is available that resolves this issue.
+
+
+
+
+
+
+
+ CVE-2021-35942 affecting package glibc 2.28
+
+ CBL-Mariner
+
+
+ true
+ 2021-08-11T06:39:32Z
+ 4820
+ Critical
+ CVE-2021-35942 affecting package glibc 2.28. A patched version of the package is available.
+
+
+
+
+
+
+
+ CVE-2018-25012 affecting package libwebp 1.0.0
+
+ CBL-Mariner
+
+
+ true
+ 2021-06-09T03:50:29Z
+ 4209
+ Critical
+ CVE-2018-25012 affecting package libwebp 1.0.0. An upgraded version of the package is available that resolves this issue.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ clamav
+
+
+ glibc
+
+
+ libwebp
+
+
+
+
+ 0:0.103.2-1.cm1
+
+
+ 0:1.0.3-1.cm1
+
+
+ 0:2.28-19.cm1
+
+
+
diff --git a/mariner/testdata/happy/cbl-mariner-2.0-preview-oval.xml b/mariner/testdata/happy/cbl-mariner-2.0-preview-oval.xml
new file mode 100644
index 0000000..5b2bfd0
--- /dev/null
+++ b/mariner/testdata/happy/cbl-mariner-2.0-preview-oval.xml
@@ -0,0 +1,95 @@
+
+
+ CBL-Mariner OVAL Definition Generator
+ 8
+ 5.11
+ 2022-01-28T13:00:50.306260678Z
+ 1643374850
+
+
+
+
+ CVE-2014-8139 affecting package unzip 6.0
+
+ CBL-Mariner
+
+
+ false
+ 6933
+ High
+ CVE-2014-8139 affecting package unzip 6.0. No patch is available currently.
+
+
+
+
+
+
+
+ CVE-2021-39924 affecting package wireshark 3.4.4
+
+ CBL-Mariner
+
+
+ false
+ 7412
+ High
+ CVE-2021-39924 affecting package wireshark 3.4.4. No patch is available currently.
+
+
+
+
+
+
+
+ CVE-2022-21309 affecting package mysql 8.0.24
+
+ CBL-Mariner
+
+
+ false
+ 7700
+ Medium
+ CVE-2022-21309 affecting package mysql 8.0.24. No patch is available currently.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ unzip
+
+
+ wireshark
+
+
+ mysql
+
+
+
+
+ 0:3.4.4-2.cm1
+
+
+ 0:6.0-19.cm1
+
+
+ 0:8.0.24-1.cm1
+
+
+
diff --git a/mariner/testdata/sad/cbl-mariner-1.0-oval.xml b/mariner/testdata/sad/cbl-mariner-1.0-oval.xml
new file mode 100644
index 0000000..19c93e2
--- /dev/null
+++ b/mariner/testdata/sad/cbl-mariner-1.0-oval.xml
@@ -0,0 +1 @@
+